绑定属性
从之前的文章中,我们知道python是动态语言——实例可以绑定任意属性。
那如果实例绑定的属性和类的属性名一样的话,会是什么情况呢?
>>> class Student(object): ... name = 'wc' ... >>> s = Student() >>> s.name 'wc' >>> Student.name 'wc' >>> s.name = 'ly' #给实例绑定name属性 >>> s.name 'ly' >>> Student.name 'wc' >>> del s.name #删除实例的name属性 >>> s.name 'wc'
可知,我们可以给实例变量绑定和类属性同样名字的变量;同时如果实例变量和类属性使用相同的名字时,实例属性将屏蔽掉类属性;最后,如果删除实例属性后,同样的名称,访问的是类的属性。
绑定方法
>>> def setAge(self,age): ... self.age = age ... >>> from types import MethodType >>> s.setAge = MethodType(setAge,s)#给实例绑定一个方法 >>> s.setAge(66) >>> s.age 66
我们来验证一下,给一个实例绑定的方法,对另外一个实例有作用吗:
>>> s2 = Student() >>> s2.setAge Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'Student' object has no attribute 'setAge'
如果,我们将方法绑定到class类,则所有实例均可调用:
>>> def setScore(self,score): ... self.score = score ... >>> Student.setScore = setSco >>> s.setScore(77) >>> s.score 77 >>> s2.setScore(88) >>> s2.score 88
使用__slots__限制实例添加属性
如果只允许对Student实例添加name和age属性,怎么办?使用__slots__:
>>> class Student(object): ... __slots__ = ('name','age') ... >>> s = Student() >>> s.name = 'wc' >>> s.age = 22 >>> s.score = 66 Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'Student' object has no attribute 'score'
由于score没有被放入__slots__中,所以实例s不能绑定属性score。
要注意:__slots__限制的作用,只对当前类的实例有用,对继承的子类是没有限制作用的:
>>> class GraStudent(Student): ... pass ... >>> g = GraStudent() >>> g.score = 88
如果子类也加上__slots__属性,那么子类的实例允许定义的属性就是自身的__slots__加上父类的__slots__:
class GraStudent(Student): __slots__ = ('addr','tel') >>> g = GraStudent() >>> g.age = 77 >>> g.addr = '南京' >>> g.tel = 128 >>> g.ip = '12.01' Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'GraStudent' object has no attribute 'ip'