1. 程式人生 > >我的Python學習筆記(四):動態新增屬性和方法

我的Python學習筆記(四):動態新增屬性和方法

一、動態語言相關概念

1.1 動態語言

  • 在執行時程式碼可以根據某些條件改變自身結構
  • 可以在執行時引進新的函式、物件、甚至程式碼,可以刪除已有的函式等其他結構上的變化
  • 常見的動態語言:Object-C、C#、JavaScript、PHP、Python、Erlang

1.2 動態型別語言

  • 在執行期間檢查資料型別的語言
  • 資料型別不是在編譯階段決定的,而是把型別繫結延後到了執行階段
  • 常見的動態型別語言:Python、Ruby、Erlang、JavaScript、swift、PHP、Perl

1.3 強型別語言

  • 一旦一個變數被指定了某個資料型別,如果不經過強制型別轉換,那麼它就永遠是這個資料型別
  • 常見的強型別語言:Java、C#、Python、Object-C、Ruby

Python是動態語言,動態型別語言,也是強型別語言。所以Python可以在執行時改變自身結構,動態新增/刪除屬性和方法。接下來將介紹Python如何動態新增屬性和方法。

二、動態新增屬性

2.1 新增物件屬性

class Person(object):
    def __init__(self, newName, newAge):
        self.name = newName
        self.age = newAge

zhangsan = Person("張三", 18)
zhangsan.addr 
= "北京" # 類物件zhangsan動態新增物件屬性addr print(zhangsan.name) # 張三 print(zhangsan.age) # 18 print(zhangsan.addr) # 北京 lisi = Person("李四", 28) print(lisi.name) # 李四 print(lisi.age) # 28 print(lisi.addr) # 'Person' object has no attribute 'addr'

由以上程式碼可知,Person類有兩個屬性:name和age。通過[物件名.屬性名

]給類物件zhangsan動態添加了物件屬性addr,而Person的另一個類物件lisi卻不能呼叫這個屬性。

注:通過物件名新增的物件屬性,只有這個物件能使用

2.2 新增類屬性

class Person(object):
    def __init__(self, newName, newAge):
        self.name = newName
        self.age = newAge

Person.addr = "北京"  # 類Person動態新增類屬性addr

zhangsan = Person("張三", 18)
print(zhangsan.name)    # 張三
print(zhangsan.age)     # 18
print(zhangsan.addr)    # 北京

lisi = Person("李四", 28)
print(lisi.name)    # 李四
print(lisi.age)     # 28
print(lisi.addr)    # 北京

由以上程式碼可知,通過[類名.屬性名]給類Person動態添加了類屬性addr,Person的類物件zhangsan和lisi都能呼叫這個屬性

注:通過類名新增的類屬性,這個類的所有物件都能使用

三、動態新增方法

類中有三種方法,例項方法,靜態方法和類方法,三種方法的區別如下:

  • 例項方法:需要繫結要一個物件上,第一個引數預設使用self,會把物件作為第一個引數傳遞進來
  • 靜態方法:使用裝飾器@staticmethod進行定義,類和物件都可以呼叫,不需要預設引數
  • 類方法:使用裝飾器@classmethod進行定義,類和物件都可以呼叫,第一個引數預設使用cls,會把類作為第一個引數傳遞進來

3.1 新增例項方法

import types

class Person(object):
    def __init__(self, newName, newAge):
        self.name = newName
        self.age = newAge

    def eat(self):
        print("---正在吃---")

def run(self):
    print("---正在跑---")

zhangsan = Person("張三", 18)
zhangsan.eat()  # ---正在吃---
zhangsan.run = types.MethodType(run, zhangsan)  # 類物件zhangsan動態新增物件方法run()
zhangsan.run()  # ---正在跑---

lisi = Person("李四", 28)
lisi.eat()  # ---正在吃---
lisi.run()  # 'Person' object has no attribute 'run'

由以上程式碼可知,Person類有一個方法:eat()方法。通過[types.MethodType(方法名, 物件名)]給類物件zhangsan動態添加了物件方法run(),同理,Person的另一個類物件lisi不能呼叫這個方法

注:通過物件名新增的物件方法,只有這個物件能使用

3.2 新增靜態方法

class Person(object):
    def __init__(self, newName, newAge):
        self.name = newName
        self.age = newAge

    def eat(self):
        print("---正在吃---")

@staticmethod
def staticRun():
    print("---正在跑---")

Person.staticRun = staticRun    # 類Person動態新增靜態方法staticRun()

Person.staticRun()  # ---正在跑---

zhangsan = Person("張三", 18)
zhangsan.eat()        # ---正在吃---
zhangsan.staticRun()  # ---正在跑---

lisi = Person("李四", 28)
lisi.eat()        # ---正在吃---
lisi.staticRun()  # ---正在跑---

由以上程式碼可知,通過[類名.靜態方法名]給類Person動態添加了靜態方法staticRun(),Person類的Person的類物件zhangsan和lisi都能呼叫這個方法

注:通過類名新增的靜態方法,這個類及這個類的所有物件都能使用

3.3 新增類方法

class Person(object):
    def __init__(self, newName, newAge):
        self.name = newName
        self.age = newAge

    def eat(self):
        print("---正在吃---")

@classmethod
def classRun(cls):
    print("---正在跑---")

Person.classRun = classRun    # 類Person動態新增類方法classRun()

Person.classRun()  # ---正在跑---

zhangsan = Person("張三", 18)
zhangsan.eat()        # ---正在吃---
zhangsan.classRun()  # ---正在跑---

lisi = Person("李四", 28)
lisi.eat()        # ---正在吃---
lisi.classRun()  # ---正在跑---

由以上程式碼可知,通過[類名.類方法名]給類Person動態添加了類方法classRun(),Person類的Person的類物件zhangsan和lisi都能呼叫這個方法

注:通過類名新增的類方法,這個類及這個類的所有物件都能使用

四、__slots__的使用

通過以上內容,我們知道了如何動態的新增屬性和方法。但是,如果我們想要限制class的屬性該怎麼辦?例如:只允許Person例項新增name和age屬性。為了達到這個目的,Python允許在定義class的時候,定義一個特殊變數__slots__來限制該class能新增的屬性。

import types
class Person(object):
    __slots__ = ("name", "age")  # 定義__slots__    
    def __init__(self, newName, newAge):
        self.name = newName
        self.age = newAge

    def eat(self):
        print("---正在吃---")

def run(self):
    print("---正在跑---")

Person.num = 100        # 類Person動態新增類屬性num

zhangsan = Person("張三", 18)
print(zhangsan.name)    # 張三
print(zhangsan.age)     # 18
print(zhangsan.num)     # 100
zhangsan.eat()          # ---正在吃---

zhangsan.addr = "北京"   # 'Person' object has no attribute 'addr'
zhangsan.run = types.MethodType(run, zhangsan)  # 'Person' object has no attribute 'run'

通過以上程式碼可知,__slots__對Person類的動態新增沒有限制,而Person類物件zhangsan不能再動態新增物件屬性和方法。

對於__slot__有以下幾個需要注意的地方:

  • __slots__只對類物件進行限制,不對類進行限制
  • __slots__不僅限制類物件的屬性,還限制類物件的方法
  • __slots__僅對當前類起作用,對繼承的子類不起作用
  • 在子類中定義__slots__,子類允許定義的屬性就是自身的__slots__加上父類的__slots__

相關推薦

Python學習筆記動態新增屬性方法

一、動態語言相關概念 1.1 動態語言 在執行時程式碼可以根據某些條件改變自身結構 可以在執行時引進新的函式、物件、甚至程式碼,可以刪除已有的函式等其他結構上的變化 常見的動態語言:Object-C、C#、JavaScript、PHP、Python、Erlang 1.2 動態型別語言 在執行期間檢查資料

python學習筆記核心模組方法

核心模組1、__builtin__模組:一、數學運算類abs(x) 求絕對值 1、引數可以是整型,也可以是複數 2、若引數是複數,則返回複數的模 complex([real[, imag]]) 建立一個複數 divmod(a, b) 分別取商和餘數 注意:整型

【整理】python學習筆記5-- pygame庫的函式方法整理

PYGAME的方法和官方文件查詢 官方文件 http://www.pygame.org/docs/   模組 簡介 pygame.BufferProxy An array protocol view

Python3學習筆記Python實現深度優先

這裡主要是用Python實現下深度優先的概念,由於程式碼寫得比較隨意,就沒有封裝成類,而是寫成一個函式 用一個列表做為實驗資料,模擬成二叉樹結構,用遞迴的方式不斷獲取二叉樹上的左節點,一直到左節點 序號超出列表範圍,然後迴歸獲取右節點,以此來實現深度優先。 以下是程式碼

Python學習筆記 列表生成式_生成器

rec triangle 小寫 ont 無限 end clas 普通 執行過程 筆記摘抄來自:https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001431

Unity3D之Mecanim動畫系統學習筆記Animation State

大致 面板 輸入 jpg any 動畫播放 速度 nsf 顯示 動畫的設置 我們先看看Animation Clip的一些設置: Loop time:動畫是否循環播放。 下面出現了3個大致一樣的選項: Root Transform Rotation:表示為播放動畫

.net core 2.0學習筆記遷移.net framework 工程到.net core

編譯 its evel hashtable ref 學習筆記 inline null 創建 在遷移.net core的過程中,第一步就是要把.net framework 工程的目標框架改為.net core2.0,但是官網卻沒有提供轉換工具,需要我們自己動手完成了

java學習筆記import語法

employee sign cnblogs java 調用 變量賦值 temp 職位 求職 Import 語法是給編譯器尋找特定類的適當位置的一種方法。 創建一個Employee 類,包括四個實體變量姓名(name),年齡(age),職位(designation)和薪水(s

python學習筆記-數據類型

rand 兩個 urn 浪費 line 平年 randint .com .cn 0. 在 Python 中的數據類型詳解 http://www.cnblogs.com/scios/p/8026576.html 1. 為什麽布爾類型(bool)的 True 和 False 分

python學習筆記字符串及字符串操作

默認 小寫字母 是不是 swap git 查找字符 英文 去掉 title 字符串   字符串可以存任意類型的字符串,比如名字,一句話等等。 字符串還有很多內置方法,對字符串進行操作,常用的方法如下: 1 name1=‘hello world‘ 2 print(nam

day3-python學習筆記

end tar upper date update size upd sdi reat 字符串方法 #字符串這些方法都不會改變原來字符串的值name = ‘beSTtest‘# new_name = name.strip()#默認是去掉空格和換行符# new_name =

Boost Python學習筆記

xtra public string 轉換 TP 簡單實現 amp dir rst 你將學到什麽 在Python中調用C++代碼時的傳參問題 基礎類型 Python的字符串是常量,所以C++函數參數中的std::string &必須為const 修改源文件(

python學習筆記

9.png fib AS 情況 一個 命名 文檔字符串 可選 交互 break 語句和 C 中的類似,用於跳出最近的一級 for 或 while 循環。 循環可以有一個 else 子句;它在循環叠代完整個列表(對於 for )或執行條件為 false (對於 while)時

Python學習筆記4容器、叠代對象、叠代器、生成器、生成器表達式

iter 有一種 ref function 但是 tool 數列 edt 叠代器類型 在了解Python的數據結構時,容器(container)、可叠代對象(iterable)、叠代器(iterator)、生成器(generator)、列表/集合/字典推導式(list,se

HADOOP學習筆記HBase

系統 唯一性 創建時間 必須 就是 入口 計算 hfile mapreduce HBase簡介 Hbase是分布式、面向列的開源數據庫(其實準確的說是面向列族)。HDFS為Hbase提供可靠的底層數據存儲服務,MapReduce為Hbase提供高性能的計算能力,Zooke

javaweb學習筆記會話管理1

目錄 會話管理 1.概念 2.cookie技術 2.1 Cookie一般處理流程 2.2 Cookie類 會話管理 1.概念 一次會話: 開啟瀏覽器 -> 訪問一些伺服器內容 -> 關閉瀏覽器。(瀏覽器A給伺服器傳送請求,訪問web程式,該次會話就

學習筆記使用K近鄰演算法檢測WebShell

1.資料蒐集       載入ADFA-LD中正常樣本資料: def load_adfa_training_files(rootdir): x=[] y=[] list = os.listdir(rootdir) for i in

Python 學習筆記[函式進階]

異常 異常捕獲 try: myfile = open('1.txt') except Exception: print('開啟檔案錯誤') else: print('開啟檔案') myfile.close() finally: print('開啟檔案結束')

Scala學習筆記apply方法說明

調用 我們 val sca 關鍵字 語法糖 方式 rgs 類型 當scala中類或者對象有一個主要用途的時候,apply方法就是一個很好地語法糖。請看下面一個簡單的例子: class Foo(foo: String) {} object Foo { def appl

python 學習筆記 資料庫壓測程式設計

這個程式碼是利用多執行緒多mysql資料庫批量插入資料,可用於mysql壓測 #!/usr/bin/python # -*- coding: utf-8 -*- from __future__ import print_function import argp