python: 理解 __getattr__, getattr ,
首先,我們看getattr,顧名思義,得到屬性。它的全部應該是getattr(object,“attribution”,None),一般情況我們這麼用getattr(object,name)
它類似於得到object.attribution的值。
getattr的用法:
比如:
>>> class test:
... cal=1
...
>>> getattr(test,"cal")
1
>>> test.cal
1
>>>
因為,cal是test的一個屬性,所以,上面的結果你是可以理解。那麼,如何看一個物件的屬性呢?
dir("物件") 就可以了。
>>> dir(test)['__doc__', '__module__', 'cal']
看看下面的例子:
>>> t={}
>>> t['a'] = "hello"
>>> t['b'] = "world"
>>> getattr(t,"a")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'dict' object has no attribute 'a'
可能你的意圖是利用getattr得到t[a]的值,但是,出現了錯誤,為什麼?
因為a不是t的屬性
>>> dir(t)
['__class__', '__cmp__', '__contains__', '__delattr__', '__delitem__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__',
'__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'clear', 'copy', 'fromkeys', 'get', 'has_key', 'items', 'iteritems', 'iterkeys', 'itervalues', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']
看到了吧,這裡面沒有“a”, __str__是t的屬性。
"{'a': 'hello', 'b': 'world'}"
>>> t.__str__()
"{'a': 'hello', 'b': 'world'}"
__getattr__的用法:
__getattr__()是僅當屬性不能在例項的__dict__或它的類(類的__dict__),或父類其__dict__中找到時,才被呼叫。一般在程式碼中包含一個對getattr()內建函式的呼叫每一個類都會用一個字典,把它包含的屬性放到自己的字典裡(這是內建的),
>>> dir(test)
['__doc__', '__module__', 'cal']>>> test.__dict__
{'__module__': '__main__', '__doc__': None, 'cal': 1}
看看下面的例子:
- #!/usr/bin/env python
- class WrapMe(object):
- def __init__(self,obj):
- print"I am in init"
- self.__data = obj
- def get(self):
- print"I am in get"
- returnself.__data
- def __repr__(self):
- print"I am in repr"
- return'self.__data'
- def __str__(self):
- print"I am in str"
- return str(self.__data)
- def __getattr__(self, attr):
- print"I am in getattr"
- return getattr(self.__data, attr)
- if __name__ == "__main__":
- wcomplex = WrapMe(3.5+4.2j)
- print wcomplex
- print wcomplex.real
- print wcomplex.get()
$./attr.py
I am in init
I am in str
(3.5+4.2j)
I am in getattr
3.5
I am in get
(3.5+4.2j)
我們分析程式如下:
- wcomplex = WrapMe(3.5+4.2j)
這時候輸出應為:I am in init
- print wcomplex
這時候呼叫了__str__ 函式
- print wcomplex.real
- def __getattr__(self, attr):
- print"I am in getattr"
- return getattr(self.__data, attr)
這時候,呼叫getattr(),也就是self.__data.attr=>(3.5+4.2j).real 得到實部3.5。
- print wcomplex.get()
因為,get方法是wcomplex的屬性。所以,直接呼叫了get()方法。沒有呼叫__getattr__()