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的属性。

>>> getattr(t,"__str__")()
"{'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}

看看下面的例子:

[python] view plain copy
  1. #!/usr/bin/env python  
  2. class WrapMe(object):  
  3.     def __init__(self,obj):  
  4.         print "I am in init"  
  5.         self.__data = obj  
  6.     def get(self):  
  7.         print "I am in get"  
  8.         return self.__data  
  9.     def __repr__(self):  
  10.         print "I am in repr"  
  11.         return 'self.__data'  
  12.     def __str__(self):  
  13.         print "I am in str"  
  14.         return str(self.__data)  
  15.     def __getattr__(self, attr):                                                                                                                                                                               
  16.         print "I am in getattr"  
  17.         return getattr(self.__data, attr)  
  18.   
  19. if __name__ == "__main__":  
  20.     wcomplex = WrapMe(3.5+4.2j)  
  21.     print  wcomplex  
  22.     print wcomplex.real      
  23.     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)

我们分析程序如下:

[python] view plain copy
  1. wcomplex = WrapMe(3.5+4.2j)  

这时候输出应为:I am in init

[python] view plain copy
  1. print  wcomplex  

这时候调用了__str__ 函数

[python] view plain copy
  1. print wcomplex.real  
我们知道,real不是实例wcomplex的属性。这时候,__getattr__将被调用。
[python] view plain copy
  1. def __getattr__(self, attr):                                                                                                                                                                               
  2.         print "I am in getattr"  
  3.         return getattr(self.__data, attr)  

这时候,调用getattr(),也就是self.__data.attr=>(3.5+4.2j).real 得到实部3.5。

[python] view plain copy
  1. print wcomplex.get()  

因为,get方法是wcomplex的属性。所以,直接调用了get()方法。没有调用__getattr__()



你可能感兴趣的:(python,object,File,Module,Class)