动态绑定属性、方法 以及 __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都是允许定义的

posted @ 2020-09-18 15:33  Alantammm  阅读(178)  评论(0编辑  收藏  举报