正常情況下,當我們定義了乙個class,建立了乙個class的例項後,我們可以給該例項繫結任何屬性和方法,這就是動態語言的靈活性。先定義class:
class
student
(object):
pass
然後,嘗試給例項繫結乙個屬性:
>>> s = student()
>>> s.name = 'michael'
# 動態給例項繫結乙個屬性
>>> print(s.name)
michael
還可以嘗試給例項繫結乙個方法:
>>>
defset_age
(self, age):
# 定義乙個函式作為例項方法
... self.age = age
...>>>
from types import methodtype
>>> s.set_age = methodtype(set_age, s) # 給例項繫結乙個方法
>>> s.set_age(25) # 呼叫例項方法
>>> s.age # 測試結果
25
但是,給乙個例項繫結的方法,對另乙個例項是不起作用的:
>>> s2 = student() # 建立新的例項
>>> s2.set_age(25) # 嘗試呼叫方法
traceback (most recent call last):
file "", line 1, in
attributeerror: 'student' object has no attribute 'set_age'
為了給所有例項都繫結方法,可以給class繫結方法:
>>>
defset_score
(self, score):
... self.score = score
...>>> student.set_score = set_score
給class繫結方法後,所有例項均可呼叫:
>>> s.set_score(100)
>>> s.score
100>>> s2.set_score(99)
>>> s2.score
99
通常情況下,上面的set_score
方法可以直接定義在class中,但動態繫結允許我們在程式執行的過程中動態給class加上功能,這在靜態語言中很難實現。
但是,如果我們想要限制例項的屬性怎麼辦?比如,只允許對student例項新增name
和age
屬性。
為了達到限制的目的,python允許在定義class的時候,定義乙個特殊的__slots__
變數,來限制該class例項能新增的屬性:
class
student
(object):
__slots__ = ('name', 'age') # 用tuple定義允許繫結的屬性名稱
然後,我們試試:
>>> s = student() # 建立新的例項
>>> s.name = 'michael'
# 繫結屬性'name'
>>> s.age = 25
# 繫結屬性'age'
>>> s.score = 99
# 繫結屬性'score'
traceback (most recent call last):
file "", line 1, in
attributeerror: 'student' object has no attribute 'score'
由於'score'
沒有被放到__slots__
中,所以不能繫結score
屬性,試圖繫結score
將得到attributeerror
的錯誤。
使用__slots__
要注意,__slots__
定義的屬性僅對當前類例項起作用,對繼承的子類是不起作用的:
>>>
class
graduatestudent
(student):
...
pass
...>>> g = graduatestudent()
>>> g.score = 9999
除非在子類中也定義__slots__
,這樣,子類例項允許定義的屬性就是自身的__slots__
加上父類的__slots__
。 Python學習之物件的動態性
物件可以使用del語句刪掉,刪掉之後將不能再呼叫該物件。也可以為物件動態的新增方法。但是動態新增的方法,python不會自動的將呼叫者繫結到self上,需要手動繫結 繫結的同時即呼叫 例如 假設某個類的例項是p,再類外,有乙個準備新增的新方法,叫做newfunc def newfunc self p...
Swift的動態性
動態性比較重要的一點就是能夠拿到某個類所有的方法 屬性,我們使用如下 來列印方法和屬性列表。動態性最常用的就是方法替換 method swizzling 將類的某個方法替換成自定義的方法,從而達到hook的作用。objc 用來將swift的api匯出給objective c和objective c ...
ruby的動態性
記住 ruby的動態特性是以self身份的轉換為基礎的。單例類先來看看什麼是單例類。大多數ruby程式中發生的都涉及包含例項方法定義的類和模組 class c def talk puts hi endend 使用下面的方法例項化和例項方法呼叫 c c.new c.talk 還可以直接給單個物件新增方...