• getattr getattribute setattr hasattr delattr


    getattr是返回对象属性value的函数,用法:getattr(object,attribute_name[,default])

    如果对象拥有属性,则返回属性value,如果对象没有该属性并且也没有定义__getattr__方法的时候,则要么抛出异常要么有default参数返回default值。

    但是,当类中定义了__getattr__的时候,在属性不存在的情况下,getattr就会调用__getattr__方法看看能不能获取到value

    以上结论适用于心事累也适用于就是累

    class C():
        a = 'abc'
            
        def __getattr__(self, name):
            print ('hhh')
            if name == 'adult':
                return True
                
            else: raise AttributeError(name)
        
    
    a=C()
    aa=getattr(a,'a')#aa为'abc'
    b=a.adult#打印hhh,b为True
    c=getattr(a,'adult',6)#打印hhh,c为True
    d=getattr(a,'ss',4)#打印hhh,d为4
    d=getattr(a,'ss')#打印hhh,抛出异常

    object.__getattribute__(self, name)
    实例instance通过instance.name访问属性name__getattribute__方法一直会被调用,无论属性name是否追溯到。如果类还定义了__getattr__方法,除非通过__getattribute__显式的调用它,或者__getattribute__方法出现AttributeError错误,否则__getattr__方法不会被调用了。如果在__getattribute__(self, attr)方法下存在通过self.attr访问属性,会出现无限递归错误。
    如下所示,ClassA中定义了__getattribute__方法,实例insA获取属性时,都会调用__getattribute__返回结果,即使是访问__dict__属性。

    class ClassA(object):
    
        def __init__(self, classname):
            self.classname = classname
    
        def __getattr__(self, attr):
            return('invoke __getattr__', attr)
    
        def __getattribute__(self, attr):
            return('invoke __getattribute__', attr)
    
    
    insA = ClassA('ClassA')
    print(insA.__dict__)
    # ('invoke __getattribute__', '__dict__')
    
    print(insA.classname)
    # ('invoke __getattribute__', 'classname')
    
    print(insA.grade)
    # ('invoke __getattribute__', 'grade')

     还有一个是setattr,如果类自定义了__setattr__,对实例属性的赋值就会调用它。需要注意的是,在__setattr__下还有self.attr的赋值操作就会出现无线递归__setattr__的情况。自己实现__setattr__有很大风险,所以一般情况都还是继承object类的__setattr__方法。

    class ClassA(object):
        def __init__(self, classname):
            self.classname = classname
    
        def __setattr__(self, name, value):
            # self.name = value  # 如果还这样调用会出现无限递归的情况
            print('invoke __setattr__')
    
    insA = ClassA('ClassA') # __init__中的self.classname调用__setattr__。
    # invoke __setattr__
    
    print(insA.__dict__)
    # {}
    
    insA.tag = 'insA'    
    # invoke __setattr__
    
    print(insA.__dict__)
    # {}

    与getattr()函数会调用__getattr__类似,setattr()函数也会调用__setattr__。setattr(object, name, values)

    而hasattr就比较简单了,只是一个简单的判断

    18年10月23日更新:

    关于hasattr的原理:

    hasattr的判断依据并不是以dir()所返回的列表为依据。

    比如:

    #!/usr/bin/env py3
    
    class a:
        pass
    
    print (dir(a))
    print (hasattr(a,"mro"))

    dir(a),返回的列表并不包含mro元素,但是用hasattr查看却是true

     也就是说,如果hasattr(a,x)函数所有返回ture的属性x组成一个集合,那么,dir()所返回的列表,是这个集合的一个子集

    再比如:

    #!/usr/bin/env py3
    
    class a:
        ss=3
        def __getattr__(self, name):
            if name == 's':
                return 5
    aa=a()
    print (dir(aa))#列表中不包含s
    print (hasattr(aa,"s"))#返回true

    delattr是用来删除属性

    需要注意的是他只能用来删除实例属性,删除类属性将报错

    #!/usr/bin/env py3
    
    class a:
        ss=3
        def __init__(self):
            self.k=4
        def __getattr__(self, name):
            if name == 's':
                return 5
    aa=a()
    delattr(aa,'k')
    #delattr(aa,'ss')#报错
    #delattr(aa,'s')#报错

    参考:

    https://www.cnblogs.com/elie/p/6685429.html

  • 相关阅读:
    牛客小白月赛16E
    洛谷P1309 瑞士轮
    洛谷P1781 宇宙总统
    洛谷P1068 分数线划定
    洛谷P1059 明明的随机数(桶排思想)
    洛谷P1177 【模板】快速排序 (归并排序)
    Python基础-----sys模块
    Python基础-----模块导入注意事项
    Python基础-----os模块
    Python基础-----random随机模块(验证码)
  • 原文地址:https://www.cnblogs.com/saolv/p/9324561.html
Copyright © 2020-2023  润新知