1、getattr
当我们访问一个不存在的属性时,会抛出异常,提示不存在这个属性,而这个异常就是__getattr__方法抛出的,其原因在于他是访问一个不存在的属性的最后落脚点,作为异常抛出的地方提示出错再适合不过了。
举例:
class A(object):
def __init__(self, value):
self.value = value
def __getattr__(self, item):
print ("into __getattr__")
return "can not find"
a = A(10)
print (a.value)
#10
print(a.name)
#into __getattr__
#can not find
可以看出,当访问存在的属性时,会正常返回,若该访问不存在,则返回__getattr__函数
源码:
def __getattr__(self, name):
return getattr(caches[DEFAULT_CACHE_ALIAS], name)
-->getattr
def getattr(object, name, default=None):
"""
getattr(object, name[, default]) -> value
Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y.
When a default argument is given, it is returned when the attribute doesn't
exist; without it, an exception is raised in that case.
getattr(object,name [,default])-> value从对象获取命名属性; getattr(x,'y')等效于xy给定默认参数时,如果该属性不提供则返回不 存在;没有它,在这种情况下会引发异常。
"""
pass
2、setattr
在对一个属性设置值的时候,会调用到这个函数,每个设置值的方式都会进入这个方法。
class A(object):
def __init__(self, value):
print("into __init__")
self.value = value
def __setattr__(self, name, value):
print("into __setattr")
if value == 10:
print("from __init__")
object.__setattr__(self, name, value)
a = A(10)
print(a.value)
'''
into __init__
into __setattr
from __init__
10
'''
在实例化的时候,会进行初始化,在__init__里,对value的属性值进行了设置,这时候会调用__setattr__方法。
需要注意的地方是,在重写__setattr__方法的时候千万不要重复调用造成死循环。
例如:
class A(object):
def __init__(self, value):
self.value = value
def __setattr__(self, name, value):
self.name = value
a = A(10)
print(a.value)
'''
[Previous line repeated 328 more times]
RecursionError: maximum recursion depth exceeded
显示递归超出限制
'''
除了上面调用object类的__setattr__避开死循环,还可以如下重写__setattr__避开循环。
解决方法:
class A(object):
def __init__(self, value):
self.value = value
def __setattr__(self, name, value):
self.__dict__[name] = value
a = A(10)
print a.value
# 10
3、delattr
__delattr__是个删除属性的方法.
class A(object):
def __init__(self, value):
self.value = value
def __delattr__(self, item):
object.__delattr__(self, item)
def __getattr__(self, item):
return ("when can not find attribute into __getattr__")
a = A(10)
print(a.value)
# 10
del(a.value)
print(a.value)
# when can not find attribute into __getattr__
delattr__也要避免死循环的问题,就如__setattr__一样,在重写__delattr,避免重复调用。
源码:
def __delattr__(self, name):
return delattr(caches[DEFAULT_CACHE_ALIAS], name)
--->delattr
def delattr(x, y): # real signature unknown; restored from __doc__
"""
Deletes the named attribute from the given object.
delattr(x, 'y') is equivalent to ``del x.y''
从给定对象中删除命名属性。 delattr(x,'y')等效于``del x.y''
"""
pass