美文网首页
使用__slots__实现动态绑定

使用__slots__实现动态绑定

作者: 码农小杨 | 来源:发表于2018-01-18 19:46 被阅读0次

    Python作为动态语言,可以实现动态绑定属性和实例方法等。

    动态绑定属性

    In [1]: class Student(object):
       ...:     pass
       ...: 
    
    In [2]: s = Student() 
    
    In [3]: s.name = "hongshaorou" 
    
    In [4]: print(s.name) 
    hongshaorou
    

    动态绑定实例方法

    In [5]: def set_age(self, age):
       ...:     self.age = age 
       ...:     
    
    In [6]: from types import MethodType
    
    In [7]: s.set_age = MethodType(set_age, s)
    
    In [8]:  s.set_age(25) 
    
    In [9]: s.age 
    Out[9]: 25
    

    给一个实例绑定的方法,对另一个实例是不起作用的

    In [10]: s2 = Student() 
    
    In [11]: s2.set_age(26)
    ---------------------------------------------------------------------------
    AttributeError                            Traceback (most recent call last)
    <ipython-input-11-eb78423c35e8> in <module>()
    ----> 1 s2.set_age(26)
    
    AttributeError: 'Student' object has no attribute 'set_age'
    

    为了给所有实例都绑定方法,可以给class绑定方法

    In [12]: def set_score(self, score):
        ...:     self.score = score 
        ...:     
    
    In [13]: Student.set_score = set_score
    
    In [14]: s.set_score(100) 
    
    In [15]: s2.set_score(100)
    

    通常情况下,上面的set_score方法可以直接定义在class中,但动态绑定允许我们在程序运行的过程中动态给class加上功能,这在静态语言中很难实现

    使用slots

    如果我们想要限制实例的属性怎么办?比如,只允许对Student实例添加name和age属性。

    为了达到限制的目的,Python允许在定义class的时候,定义一个特殊的__slots__变量,来限制该class实例能添加的属性:

    In [16]: class Student(object):
        ...:     __slots__ = ('name', 'age') 
        ...:     
    
    In [17]: s = Student()
    
    In [18]: s.name = 'hongshaorou' 
    
    In [19]: s.age = 26
    
    In [20]: s.score = 100
    ---------------------------------------------------------------------------
    AttributeError                            Traceback (most recent call last)
    <ipython-input-20-b5a9e82f869f> in <module>()
    ----> 1 s.score = 100
    
    AttributeError: 'Student' object has no attribute 'score'
    

    由于'score'没有被放到__slots__中,所以不能绑定score属性,试图绑定score将得到AttributeError的错误。

    使用__slots__要注意,__slots__定义的属性仅对当前类实例起作用,对继承的子类是不起作用的:

    In [21]: class GraduateStudent(object):
        ...:     pass
        ...: 
    
    In [22]: g = GraduateStudent()
    
    In [23]: g.score = 100
    

    除非在子类中也定义__slots__,这样,子类实例允许定义的属性就是自身的__slots__加上父类的__slots__

    相关文章

      网友评论

          本文标题:使用__slots__实现动态绑定

          本文链接:https://www.haomeiwen.com/subject/ivnwoxtx.html