【python】魔法之__getattribute__,__getattr__的用法总结

1:当定义一个类的实例时,毫无疑问首先调用类的初始化函数 def __init__(self)。

2:当我们用的实例去访问实例的属性时,则首先调用方法  def __getatttibute__(self)

3:   在类内没有方法 def __getattr__(self) 的前提下,如果用类的实例去调用一个实例不存在的属性时,则会抛出AttributeError异常常。

下面看代码:

class A(object):

    AA = 'abc'

    def __init__(self,name):

        self.myname=name

    def __getattribute__(self,x):
        print("__getattribute__() is called")
        print("x is",x)
        return object.__getattribute__(self,x)


a=A('zhangsan')
a.myname
b=a.AA
print(b)
a.zz    #类A没有zz属性,则会抛出异常

输出结果为:

__getattribute__() is called
x is myname
__getattribute__() is called
x is AA
abc
__getattribute__() is called
x is zz
Traceback (most recent call last):
  File "/home/lanliang/Projects/UNet-pytorch-master/test1.py", line 41, in <module>
    a.zz
  File "/home/lanliang/Projects/UNet-pytorch-master/test1.py", line 12, in __getattribute__
    return object.__getattribute__(self,x)
AttributeError: 'A' object has no attribute 'zz'

上面是类A没有 __getattr__方法,下面看看有加上此方法的情况。

class A(object):

    AA = 'abc'

    def __init__(self,name):

        self.myname=name

    def __getattribute__(self,x):
        print("__getattribute__() is called")
        print("x is",x)
        return object.__getattribute__(self,x)

    def __getattr__(self, me):
        print("__getattr__() is called ",me + " from getattr")
        return None


a=A('zhangsan')
a.myname
b=a.AA
print(b,'\n')

c=a.zz
print(c)

输出结果为:

__getattribute__() is called
x is myname
__getattribute__() is called
x is AA
abc 

__getattribute__() is called
x is zz
__getattr__() is called  zz from getattr
None

上面可以看出,当实例a调用类A内不存在的属性时,也会优先先调用方法 __getattr__,再去调用__getattr__方法。

总结:

1:__getattribute__方法。即在上面代码中,当我调用实例对象a的xx属性时,不会直接打印,而是把xx的值作为实参传进__getattribute__方法中(参数x是我随便定义的,可任意起名),经过一系列操作后,再把xx的值返回。Python中只要定义了继承object的类,就默认存在属性拦截器,只不过是拦截后没有进行任何操作,而是直接返回.在对象属性的调用中,如果没有调用了不存在的属性,则Python解释器会报错.

2: 要解决调用不存在的属性且不报错,则需要重写__getattr__方法去覆盖原方法去实现,比如返回None。

猜你喜欢

转载自blog.csdn.net/lyl771857509/article/details/84730140