__getattribute__

__getattribute__

1、回顾__getattr__

__getattr__只有在使用点调用属性且属性不存在的时候才会触发
'''
__getattr__只有在使用点调用属性且属性不存在的时候才会触发     比较有用
__delattr__删除属性的时候会触发
__setattr__添加/修改属性会触发它的执行
当你自己写__getattr__、__delattr__、__setattr__方法,系统会调用你写的方法,如果没写,系统调用默认
'''
class Foo:
    x=1
    def __init__(self,y):
        self.y=y

    def __getattr__(self, item):
        print('----> from getattr:你找的【%s】属性不存在'%item)


    def __setattr__(self, key, value):
        print('----> from setattr')
        if type(value) is str:      #判断v值为字符串类型,才能加入字典
            print('执行设置操作')
            # self.key=value #这就无限递归了,你好好想想
            self.__dict__[key] = value.upper()  # 应该使用它   最底层的操作就是在设置属性字典   upper(str)类型的全部大写
        else:
            print('必须是str才能加入')

    def __delattr__(self, item):
        print('----> from delattr')
        # del self.item #无限递归了
        #self.__dict__.pop(item)    #同理直接操作字典

f1=Foo(10)
f1=Foo('asdfgh')
print(f1.__dict__)

#print(f1.ya)
# print(getattr(f1,'y'))  #本质就是len(str)------>str.__len__()
# print(getattr(f1,'不存在的'))   #如果这个参数不存在,那么会执行 __getattr__的参数,如果没有定义__getattr__,会走系统默认的(报错)

2、__getattribute__

(1)__getattribute__不管属性存不存在都会触发
(2)只有在抛出AttributeError异常时才会触发__getattr__函数
class test:
    def __init__(self,x):
        self.x = x
    def __getattr__(self, item):    #当两个函数都存在时,只有__getattribute__抛出AttributeError才会执行
        print('执行了__getattr__|找不到你想要的参数%s'%item)


    def __getattribute__(self, item):       #当实例调用参数值时存不存在都会执行此函数
        print('执行了__getattribute__')
        raise AttributeError('AttributeError异常')
        #raise 模拟抛出异常(没事找事),如果抛AttributeError会执行__getattr__函数,不抛不会执行,只有AttributeError异常可以


t1 = test(8)    #实例化类,会触发test的类的构造函数,得到对象t1
#print(t1.x)
t1.bucunzai     #t1.一个不存在的值时,会触发类中的__getattr__方法

原文地址:https://www.cnblogs.com/shangpolu/p/6232621.html