python cookbook第三版学习笔记十二:类和对象创建新的类或实例属性

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python cookbook第三版学习笔记十二:类和对象创建新的类或实例属性相关的知识,希望对你有一定的参考价值。

先介绍几个类中的应用__getattr__,__setattr__,__get__,__set__,__getattribute__,。
__getattr__:当在类中找不到attribute的时候,会调用__getattr__,并执行其中的自定义代码。所有在类中定义的属性都包含在__dict__中,也就是说如果在__dict__中找不到对应的属性名,则__getattr__被触发。
class get_try(object):
    def __init__(self,value):
        self.value=value
    def __getattr__(self, item): #当找不到类中的属性的时候,将会被调用
        self.value=item

if __name__ == "__main__":
    g=get_try(‘value‘)
    g.value1   #调用了g.value1,value1传入__getattr__的item.调用__getattr后,value=value1
    print g.value
print g.__dict_
 
E:\python2.7.11\python.exe E:/py_prj/fluent_python/chapter7.py
value1
{‘value‘: ‘value1‘}
结果打印的时候g.value的值是value1
 
__getattribute__:无条件被调用,如果同时定义了__getattr__, 则__getattr__不会被调用。
class get_try(object):
    def __init__(self,value):
        self.value=value
    def __getattr__(self, item):
        self.value=item
    def __getattribute__(self, item):
        print item

if __name__ == "__main__":
    g=get_try(‘value‘)
    g.value1
E:\python2.7.11\python.exe E:/py_prj/fluent_python/chapter7.py
value1
结果和之前一样。
 
__setattr__当需要自己对属性进行定义的时候,会被调用。比如self.att=value就会变成self.__setattr__(“att”,value)class get_try():    def __init__(self,value):
        self.value=value
    def __getattr__(self, item):
        self.value=item
    def __getattribute__(self, item):
        print item
    def __setattr__(self, key, value):
        self.__dict__[key]=value


if __name__ == "__main__":
    g=get_try(‘value‘)
    g.value1=3
    print g.value1
    print g.__dict__
E:\python2.7.11\python.exe E:/py_prj/python_cookbook/chapter8.py
3
{‘value1‘: 3, ‘value‘: ‘value‘}
需要注意的是在__setattr__的时候不能进行self.key=value的赋值,因为这个方式会使得不停调用self.__setattr__。这样会形成无穷的递归循环。最终导致堆栈溢出异常。当我们调用的时候,报的错误就像下面这种
  File "E:/py_prj/python_cookbook/chapter8.py", line 107, in __setattr__
    self.key=value
  File "E:/py_prj/python_cookbook/chapter8.py", line 107, in __setattr__
    self.key=value
RuntimeError: maximum recursion depth exceeded
其实我们不实现__setattr__的时候,在给属性赋值的时候也会隐含的调用这个函数。那么这样实现的好处是什么呢?好处是我们可以指定给哪些属性进行赋值。
class get_try():
    def __init__(self,value):
        self.value=value
    def __getattr__(self, item):
        self.value=item
    def __getattribute__(self, item):
        print item
    def __setattr__(self, key, value):
        if key == ‘value1‘:
            print ‘incorrect key‘
        else
:
            self.__dict__[key]=value


if __name__ == "__main__":
    g=get_try(‘value‘)
    g.value1=3
    g.value2=4
    print g.__dict__
E:\python2.7.11\python.exe E:/py_prj/python_cookbook/chapter8.py
incorrect key
{‘value2‘: 4, ‘value‘: ‘value‘}
上面的代码中,当对value1进行赋值的时候,首先进行判断。如果是value1则打印incorrect key。所以看到当对value2进行赋值的时候是成功的。同样的道理,我们可以用__setattr__在防止后续对类中已有的属性进行赋值:
class get_try():
    def __init__(self,value):
        self.value=value
    def __getattr__(self, item):
        self.value=item
    def __getattribute__(self, item):
        print item
    def __setattr__(self, key, value):
        if key in self.__dict__:
            print ‘already exist‘
        else
:
            self.__dict__[key]=value

if __name__ == "__main__":
    g=get_try(‘value‘)
    g.value=4
    g.value1=3
    print g.__dict__
E:\python2.7.11\python.exe E:/py_prj/python_cookbook/chapter8.py
already exist
{‘value1‘: 3, ‘value‘: ‘value‘}
上面的代码中,首先判断赋值的对象是否已存在,如果存在则打印already exist
 



































































以上是关于python cookbook第三版学习笔记十二:类和对象创建新的类或实例属性的主要内容,如果未能解决你的问题,请参考以下文章

python cookbook第三版学习笔记二:字典

python cookbook第三版学习笔记九:函数

python cookbook第三版学习笔记三:列表以及字符串

python cookbook第三版学习笔记四:文本以及字符串令牌解析

python cookbook第三版学习笔记十三:类和对象描述器

python cookbook第三版学习笔记十一:类和对象调用父类的方法