zoukankan      html  css  js  c++  java
  • 动态绑定属性、方法 以及 __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都是允许定义的

  • 相关阅读:
    Could not resolve com.android.support:appcompat-v7:28.0.0 错误处理
    解决 Could not resolve com.android.tools.build:gradle:3.1.3
    https://maven.google.com 连接不上的解决办法(转)
    jquery操作select(取值,设置选中)
    django 使用 request 获取浏览器发送的参数
    jquery下载,实时更新jquery1.2到最新3.3.1所有版本下载
    myeclipse 8.5反编译插件失效
    再探java基础——对面向对象的理解(2)
    庖丁解牛FPPopover
    去大连
  • 原文地址:https://www.cnblogs.com/alantammm/p/13691537.html
Copyright © 2011-2022 走看看