setattr(x,y,z) ----> x.y=z
setattr(Test,'x'.1) Test 为类对象
getattr(object,name[,default])
getattr(x,'y') -----> x.y
不会触发__getattribute__
__getattr__:
如果实例instance
通过instance.name
访问属性name,
如果类中没有定义name,会触发此方法,
类中定义了name 这个属性,不会触发此方法
注意:如果在__getattr__(self, attr)
存在通过self.attr
访问属性,会出现无限递归错误。
__getattribute__
如果实例instance
通过instance.name
访问属性name,
不管类中有没有定义name 属性,都会触发此方法,
注意:如果在__getattribute__(self, attr)
方法下存在通过self.attr
访问属性,会出现无限递归错误
如果类中定义了__getattr__
方法,除非通过__getattribute__
显式的调用它,或者__getattribute__
方法出现AttributeError
错误,否则__getattr__
方法不会被调用
- test.x =1
- print(test.x) 设置/访问属性 每次都会调用 __getattribute__方法
test.x =1 ---->调用__setattr__,不建议自己实现
print(test.x) ====> 如果x属性没有设置__getattribute__会去调用 __getattr__方法
class Test1:
def __init__(self):
self.s = 2
def __getattr__(self, key):
print("__getattr___", key)
if key == 'x':
return 'default x'
return key
T = Test1()
print(T.s)
#输出
# 2
print(T.f) #类没有f属性,就调用了__getattr__
#输出
#__getattr___ f
#f
class Test3():
def __init__(self):
self.s = 2
def __getattribute__(self, key):
print('__getattribute__')
if key == 'x':
return 'default x'
else:
return key
----------------------
T =Test3() #不管类里有没有该属性 都调用了__getattribute__
print(T.s)
#输出:
#__getattribute__
#s
print(T.x)
# 输出
# __getattribute__
# default
# x
class Test2:
def __init__(self):
self.s = 2
def __getattribute__(self, key):
print('__getattribute__')
if key == 'x':
pass
# return 'default x'
else:
raise AttributeError
def __getattr__(self, key):
print("__getattr___", key)
return key
--------------------------------
T = Test2()
#输出
# print(T.x)
#__getattribute__
#None
print(T.f) # __getattribute__ 抛出AttributeError,调用 __getattr___
#输出
# __getattribute__
# __getattr___ f
# f