1. 程式人生 > 其它 >Python學習之動態繫結

Python學習之動態繫結

動態語言的靈活性,就是當我們定義一個class,建立class的例項後,可以給該例項繫結任何屬性和方法。

動態繫結屬性

定義一個Student類

class Student(object):
    def __init__(self):
        self

給例項繫結一個屬性

# 建立一個例項
s = Student()
# 動態給例項繫結屬性
s.name = "rissa"
print("name:%s" % s.name)

結果

name:rissa

動態繫結方法

需要定義一個函式作為例項方法,然後使用MethodType給例項繫結方法。

from types import
MethodType class Student(object): def __init__(self): self # 定義一個函式作為例項方法 def set_score(self, score): self.score = score # 建立一個例項 s = Student() # 給例項動態繫結一個方法 s.set_score = MethodType(set_score, s) s.set_score("99") print("score:%s" % s.score)

結果

score:99

但是,給一個例項繫結的方法,對另一個例項是不起作用的

# 給例項動態繫結一個方法或屬性後,對另一個例項不起作用
s2 = Student()
s2.set_score("96")
print("score:%s" % s2.score)

結果

為了給所有例項都繫結方法,可以給class繫結方法,給class繫結方法後,所有例項均可呼叫。

class Student(object):
    def __init__(self):
        self

   
# 定義一個函式作為例項方法
def set_score(self, score):
    self.score = score

# 給class繫結方法
Student.set_score = set_score

# 建立例項 s = Student() s2 = Student() s.set_score("98") print("例項s:%s" % s.score) s2.set_score("96") print("例項s2:%s" % s2.score)
例項s:98
例項s2:96

使用__slots__

當給例項動態繫結屬性時,想要限制屬性,使用__slots__變數來限制新增的屬性。

class Student(object):
    def __init__(self):
        self

    __slots__ = ("name", "score")  # 以元組的方式


# 建立一個例項
s = Student()
# 動態給例項繫結屬性
s.name = "rissa"
print("name:%s" % s.name)
s.score = "95"
print("score:%s" % s.score)
s.age = 18
print("age:%s" % s.age)

結果

由於“age”沒有被放到__slots__中,所以繫結錯誤。

使用__slots__注意,__slots__定義的屬性只對當前類例項有效,對繼承的字類的例項是無用的,除非在子類中也定義__slots__。

使用@property

在繫結屬性時,我們直接把屬性暴露出去,沒辦法檢查引數,導致可以把屬性會被隨便更改。

我們可以使用setter和getter方法,在setter方法裡面限制引數。

class Student(object):
    def get_score(self):
        return self._score

    def set_score(self, value):
        if not isinstance(value, int):
            raise ValueError('score must be an integer!')
        if value < 0 or value > 100:
            raise ValueError('score must between 0~100!')
        self._score = value


s = Student()
s.set_score(100)
print("score:", s.get_score())

結果

score: 100

上述是呼叫方法的形式來訪問類的變數,那麼有沒有既能檢查引數,又可以用類似屬性這樣簡單的方式來訪問類的變數呢?需要使用Python內建的裝飾器@property

負責把一個方法變成屬性呼叫。

class Student(object):
    @property
    def score(self):
        return self._score

    @score.setter
    def score(self, value):
        if not isinstance(value, int):
            raise ValueError('score must be an integer!')
        if value < 0 or value > 100:
            raise ValueError('score must between 0~100!')
        self._score = value


s = Student()
s.score = 99  # 實際上轉換成了set_score
print("score:", s.score) # 實際上轉換成了get_score

結果

score: 99

@property把一個getter方法變成了屬性,然後又建立了另一個裝飾器@score.setter負責把一個setter方法變成屬性賦值