Python 作為一門動態(tài)語言,我們可以動態(tài)的給對象添加屬性或方法,而不是必須一開始就在類中聲明好。關(guān)于動態(tài)添加屬性和方法,本文總結(jié)了以下幾個點:
- 動態(tài)添加對象屬性
- 動態(tài)添加類屬性
- 動態(tài)添加對象方法
- 動態(tài)添加類方法
- 動態(tài)添加靜態(tài)方法
__slots__
動態(tài)添加對象屬性
直接使用 對象.屬性名 = 屬性值 進行添加:
class Demo(object):
pass
d = Demo()
d.test = "我是動態(tài)添加的"
print(d.test)
運行結(jié)果:
我是動態(tài)添加的
動態(tài)添加類屬性
同上,直接使用 類名.屬性名 = 屬性值 進行添加:
class Demo(object):
pass
d = Demo()
Demo.desc = "我是 Demo 類"
print(Demo.desc)
print(d.desc)
運行結(jié)果:
我是 Demo 類
我是 Demo 類
動態(tài)添加對象方法
由于 Python 實例方法規(guī)定第一個參數(shù)必須是當(dāng)前實例的一個引用,所以我們需要在調(diào)用方法時將當(dāng)前的實例傳入,可以有兩種實現(xiàn)方式:
- 每次調(diào)用時都傳入實例引用
- 使用
types模塊中的MethodType方法進行綁定
先看第一種方式:
class Demo(object):
def __init__(self,desc):
self.desc = desc
def show(self):
return self.desc
d = Demo("我是 demo")
d.show = show
print(d.show(d))
運行結(jié)果:
我是 demo
這種方式的缺點是每次調(diào)用 show 方法時都需要傳入當(dāng)前實例引用,我們還可以使用 types 模塊中的 MethodType 方法進行一次性綁定:
from types import MethodType
class Demo(object):
def __init__(self,desc):
self.desc = desc
def show(self):
return self.desc
d = Demo("我是 demo")
# 使用 MethodType 方法動態(tài)綁定實例方法
d.show = MethodType(show,d)
print(d.show())
運行結(jié)果:
我是 demo
動態(tài)添加類方法
動態(tài)添加類方法,只需在使用 @classmethod 裝飾器裝飾相應(yīng)的方法,再添加給類對象:
class Demo(object):
pass
@classmethod
def desc(cls):
print("我是類方法")
Demo.desc = desc;
Demo.desc()
Demo().desc()
運行結(jié)果:
我是類方法
我是類方法
動態(tài)添加靜態(tài)方法
和動態(tài)添加類方法的方式一樣,目標方法使用 @staticmethod 裝飾器裝飾即可:
class Demo(object):
pass
@staticmethod
def desc():
print("我是靜態(tài)方法")
Demo.desc = desc;
Demo.desc()
Demo().desc()
運行結(jié)果:
我是靜態(tài)方法
我是靜態(tài)方法
__slots__
如果我們不想讓對象動態(tài)添加屬性或方法,可以使用 __slots__ 類屬性加以限制,該屬性是一個元組,元組中的元素是被允許添加的屬性或方法名,在允許列表之外的方法和屬性名無法被添加。
from types import MethodType
class Demo(object):
# 對添加的屬性或方法進行限制
__slots__ = ("desc","show")
def show(self):
return self.desc
d = Demo()
d.desc = "我是一個小對象"
d.show = MethodType(show,d)
print(d.show())
運行結(jié)果:
我是一個小對象
如果我們嘗試添加不被運行的方法或?qū)傩?,會引發(fā)異常:
from types import MethodType
class Demo(object):
# 對添加的屬性或方法進行限制
__slots__ = ("desc","show")
d = Demo()
d.test = "Test"
運行結(jié)果:
Traceback (most recent call last):
File "C:\Users\Charley\Desktop\py\py.py", line 8, in <module>
d.test = "Test"
AttributeError: 'Demo' object has no attribute 'test'
完。