动态绑定属性、方法 以及 __slots__
通常我们在定义一个类了之后,可以给类的实例再绑定任何属性和方法,这是动态语言的灵活性
1.动态绑定属性
1> 给实例绑定属性,只对该实例生效,别的实例并没有该属性
class Demo(): pass demo1 = Demo() ##给demo1绑定新的属性 demo1.name = '新绑定的属性' print(demo1.name) #输出 新绑定的属性
2>给类绑定属性,对所有实例都生效
class Demo(): pass demo1 = Demo() Demo.name = 'new' print(demo1.name)#输出new 就算是先声明实例,后绑定类属性也是ok的,因为实例对象中-类对象指针 指向的Demo已经有了这个新的属性
2.动态绑定方法
1>给实例绑定方法,有两种方式
a.方法1 需要手动告诉实例对象
class Demo(): pass def func1(self): return ('新绑定的方法返回') demo1=Demo() demo1.func1 = func1 print(demo1.func1())##这里会报错,没有传递self进去 print(demo1.func1(demo1))##正确输出 新绑定的方法返回
因为执行demo1.func1()的时候,类对象指针指向的Demo中没有这个方法,所以python并不知道这个func1()是不是对象demo1的成员方法,所以需要手动传递对象demo1进去告诉它
b.方法2 一般给实例动态绑定方法,推荐使用MethodType
from types import MethodType class Demo(): pass def func1(self): return ('新绑定的方法返回') demo1=Demo() demo1.func1 = MethodType(func1,demo1) print(demo1.func1())#正确输出 新绑定的方法返回
直接把这个方法变成demo1的成员方法,直接调用
2>给类绑定方法
from types import MethodType class Demo(): pass def func1(self): return ('新绑定的方法返回') demo2 = Demo() Demo.func1 = func1 demo1=Demo() print(demo1.func1())#正确输出 print(demo2.func1())#正确输出 #当然用MethodType也可以 Demo.func2 = MethodType(func1,Demo) print(demo1.func2())#正确输出
2.但是,当我们想要限制实例的属性的时候怎么办?比如只允许给Demo实例添加name 和 age两个属性
使用__slots__
class Demo(object): __slots__ = ('name', 'age') # 用 tuple 定义允许绑定的属性名称
例:
class Demo(): __slots__=('name','age') demo1=Demo() demo1.name = 'jack' demo1.age = 23 demo1.sex = 'male' #报错 'Demo' object has no attribute 'sex'
但是这个限制对子类并没有影响
例:
class Child(Demo): pass chi = Child() chi.sex = 'male'#不会报错
除非对子类也加上__slots__,这样子类的实例属性允许定义的属性就是自身的__slots__加上父类的__slots__。
class Child(Demo): __slots__=('sex',) chi = Child() chi.sex = 'male' chi.name = 'Tom' chi.age = 25
子类中sex/name/age都是允许定义的