Python是動態語言,動態類型語言,也是強類型語言。因此Python能夠在運行時改變自身結構,動態添加/刪除屬性和方法。接下來將介紹Python如何動態添加屬性和方法。swift
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卻不能調用這個屬性。函數
注:經過對象名添加的對象屬性,只有這個對象能使用spa
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都能調用這個屬性對象
注:經過類名添加的類屬性,這個類的全部對象都能使用繼承
類中有三種方法,實例方法,靜態方法和類方法,三種方法的區別以下:ip
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不能調用這個方法it
注:經過對象名添加的對象方法,只有這個對象能使用編譯
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都能調用這個方法class
注:經過類名添加的靜態方法,這個類及這個類的全部對象都能使用import
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都能調用這個方法
注:經過類名添加的類方法,這個類及這個類的全部對象都能使用
經過以上內容,咱們知道了如何動態的添加屬性和方法。可是,若是咱們想要限制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__有如下幾個須要注意的地方: