动态绑定实例属性:
>>> class Student(object):
... pass
...
>>> s = Student()
>>> s.name = 'Michael' #动态给实例绑定一个属性
>>> print(s.name)
Michael
>>>
复制代码
给实例动态绑定方法:
>>> def set_age(self, age): #定义一个函数作为实例方法
... self.age = age
...
>>> from types import MethodType
>>> s.set_age = MethodType(set_age, s) #给实例绑定一个方法
>>> s.set_age(24) #调用实例方法
>>> s.age #测试结果
24
复制代码
但是对另外的实例式不能绑定的:
>>> s2 = Student() #创建新的实例
>>> s2.set_age(24) #尝试调用方法
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Student' object has no attribute 'set_age'
>>>
复制代码
为了给所有实例绑定方法,我们可以给class 绑定方法:
>>> def set_score(self, score):
... self.score = score
...
>>> Student.set_score = set_score
>>> s.set_score(100)
>>> s2.set_score(99)
>>> s.score
100
>>> s2.score
99
复制代码
通过以上我们可以知道,set_score 可以直接定义在class中,但有了动态绑定,我们就可以在程序运行的 过程中给class加上方法。这在静态语言中是很难实现的。
通过__slots__变量,限制class实例属性的添加:
>>> class Student(object):
... __slots__ =('name', 'age') #用tuple定义允许绑定的属性名称
...
>>> s = Student()
>>> s.name = 'Michel' #绑定属性‘name’
>>> s.age = 25 #绑定属性‘age’
>>> s.score = 99 #绑定属性‘score’
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Student' object has no attribute 'score'
复制代码
以上可以发现,socre是不能绑定的,给出了报错提示。就是因为没有放到__slots__中
__slots__要注意,只对当前类实例起作用,对于继承类不起作用:
>>> class GraduateStudent(Student):
... pass
...
>>> g = GraduateStudent()
>>> g.score = 999
>>> g.score
999
复制代码
如果子类也需要限制属性的添加,那么就添加上__slots__:
>>> class GoodStudent(Student):
... __slots__ =('score') #使用__slots__让子类的 score 属性可以被添加
...
>>> g = GoodStudent()
>>> g.score = 99
>>> g.score
99
复制代码
总结:
1、属性可以被动态绑定。
2、方法也可以被动态绑定,但不是当前实例是不能绑定到的,如果不是当前实例也需要绑定,那么要在class中统一绑定
3、__slots__ 指定可以被绑定的属性。
复制代码