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

  • 相关阅读:
    【BZOJ3670】【NOI2014】动物园(KMP算法)
    【BZOJ4372】烁烁的游戏(动态点分治)
    【BZOJ3730】震波(动态点分治)
    【BZOJ3924】幻想乡战略游戏(动态点分治)
    【BZOJ1095】捉迷藏(动态点分治)
    动态点分治
    【BZOJ2333】棘手的操作(左偏树,STL)
    【BZOJ4816】数字表格(莫比乌斯反演)
    【BZOJ3506】排序机械臂(Splay)
    【BZOJ2693】jzptab(莫比乌斯反演)
  • 原文地址:https://www.cnblogs.com/alantammm/p/13691537.html
Copyright © 2020-2023  润新知