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