Python动态类和动态方法的创建和调用
生活随笔
收集整理的這篇文章主要介紹了
Python动态类和动态方法的创建和调用
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
借助于python的動態語言特性,很容易對對象進行添加方法或者屬性,這也是python的靈活之一。
動態生成類的屬性及其方法
在某些情況可能要根據不同的參數來動態生成不同的實例方法、靜態方法、類方法。下面的例子中則展示了如何動態地向類中添加屬性和方法。
import typesclass Person():def __init__(self,name): self.name = name li = Person('Lily') li.age = 20 # 實例屬性添加,僅對當下實例有效 tom = Person('Tom') print(tom.age) # 'Person' object has no attribute 'age'Person.age = None # 類屬性添加 print(tom.age) # Nonedef eat(self): print('%s正在吃東西。。'%self.name) li.eat = types.MethodType(eat, li) # 實際上python所有類都是type類的實例對象,動態添加了Person的實例方法 li.eat() @staticmethod def test(): print('這是一個靜態方法。')Person.test = test # 動態添加動態方法 Person.test() @classmethod def test(cls): print(cls.age) # None,訪問動態創建的ageprint('這是一個類方法。')Person.test = test # 動態添加類方法 Person.test() class test(object): __slots__ = ('name','age') # 使用slots來將屬性固定,不允許增刪動態地創建類
由于所有類都是type類的對象,所以也可以通過type動態地創建類。
Test = type('Test',(object,),{'num':0}) # 所有類都是type的對象,param1為類名,param2為繼承對象,num為類屬性,方法class Test(object): # 與上述代碼等效num = 0如果需要添加屬性方法,則在相應的傳參字典中添加對應的方法,例如:
Test = type('Test',(object,),{'num':0, 'foo': fun})動態訪問類中的屬性方法
動態地方法類中的屬性方法,也是一種反射機制。python中的反射/自省的實現,是通過hasattr、getattr、setattr、delattr四個內置函數實現的,其實這四個內置函數不只可以用在類和對象中,也可以用在模塊等其他地方,只是在類和對象中用的很多,所以單獨提出來進行解釋。
- hasattr(key) # 返回的是一個bool值,判斷某個成員或者屬性在不在類或者對象中
- getattr(key,default=xxx) # 獲取類或者對象的成員或屬性,如果不存在,則會拋出AttributeError異常,如果定義了default那么當沒有屬性的時候會返回默認值。
- setattr(key,value)假如有這個屬性,那么更新這個屬性,如果沒有就添加這個屬性并賦值value
- delattr(key)刪除某個屬性
其用法如下所示:
''' 學習中遇到問題沒人解答?小編創建了一個Python學習交流QQ群:725638078 尋找有志同道合的小伙伴,互幫互助,群里還有不錯的視頻學習教程和PDF電子書! ''' class Foo:def __init__(self,name,age):self.name=nameself.age=agedef show(self):return self.name,self.ageobj=Foo("Tom",18) print(getattr(obj,"name")) # Tom setattr(obj,"k1",eat) print(obj.k1) # <function eat at 0x00000162CAD661F0> print(hasattr(obj,"k1")) # True delattr(obj,"k1") show_fun=getattr(obj,"show") print(show_fun()) # ('Tom', 18)動態訪問普通全局函數
有時候需要通過函數名來動態訪問全局的函數,那么依然有三種方法。
- 通過eval,不同由于考慮到安全因素,不能直接這樣去寫,可能會得到惡意代碼
- 通過建立字典,事先將需要調用的函數全部放入字典,缺點是每增加一個動態函數,就要更改字典:
- 通過調用global()來使用
global()維護了一個全局的變量列表,其實現過程和方式2類似,具體使用時通```global().get(fun_name)來完成。
類中其他內建屬性方法(魔術方法)
- __init__ # 構造初始化函數,__new__之后運行
- __new__ # 創建實例所需的屬性,類似于構造方法
- __call__ # 可以使得類的實例通過function方式訪問
- __class__# 實例所在的類,實例.__class__
- __str__ # 實例的字符串表示,可讀性高
- __repr__ # 實例的字符串表示,準確性高
- __del__ # 刪除實例引用,類似于析構方法
- __dict__ # 實力自定義屬性,vars(實例.__dict__)
- __doc__ # 類文檔,help(類或者實例)
- __bases__ #當前類的所有父類
- __getattribute__#屬性訪問攔截器
結尾給大家推薦一個非常好的學習教程,希望對你學習Python有幫助!
Python基礎入門教程推薦:更多Python視頻教程-關注B站:Python學習者
Python爬蟲案例教程推薦:更多Python視頻教程-關注B站:Python學習者
總結
以上是生活随笔為你收集整理的Python动态类和动态方法的创建和调用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python中list复制引发的问题
- 下一篇: Python基础练习题,你会吗?