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。