面向对象高级之 __getattr__,__setattr__,__delattr__

Posted guodengjian

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面向对象高级之 __getattr__,__setattr__,__delattr__相关的知识,希望对你有一定的参考价值。

__getattr__

拦截对象的点号运算。
当对为定义的属性名称和实例进行点号运算时,就会用属性名作为字符串调用这个方法。如果继承树可以找到该属性,则不调用此方法

class empty:
    def __getattr__(self,attrname):
        if attrname == 'age':
            return 40
        else:
            return AttributeError,attrname

# `__getattr__`只有在使用点调用属性且属性不存在的时候才会触发
x = empyte()
print(x.age) #40
print(x.name)  #报错

__serattr__

拦截所有属性的赋值语句。
如果定义了这个方法,self.attr = value 就会变为 self.__setattr__(‘attr‘,value)
当在__setattr__方法内对属性进行赋值时,不可使用self.attr = value,因为他会再次
调用 self.__setattr__(‘attr‘,value),则会形成无限递归,导致堆栈溢出异常。应该通过对属性字典做索引运算来赋值任何实例属性,也就是使用self.__dict__[‘name‘]=value

class PrivateExc(Exception):
    pass
class Privacy:
    def __setattr__(self,attrname,value):
        if attrname in self.privates:
            raise PrivateExc(attrname,self)
        else:
            self.__dict__[attrname] = value

class Test1(privacy):
    privates = ['age',]

class Test2(privacy):
    pricates = ['name','age']
    def __init__(self):
        self.__dict__['name']='sun'

__delattr__

删除属性的时候触发
注意无限递归的问题,不要在__delattr__内部直接使用del删除属性

def __delattr__(self,item):
    #del self.item 这样就无限递归了
    self.__dict__.pop(item) #正确的方式

以上是关于面向对象高级之 __getattr__,__setattr__,__delattr__的主要内容,如果未能解决你的问题,请参考以下文章

Python面向对象高级

面向对象之__setattr__,__delattr__,__getattr__

六 面向对象高级属性

面向对象高级

python自动化开发-[第八天]-面向对象高级篇与网络编程

面向对象__getattr__//__setattr__