Python中的getattr()和__getattr__方法

 
原文链接:https://blog.csdn.net/wangyiyan315/article/details/14229981

getattr()
先在python解释器看下getattr()的帮助 :
Help on built-in function getattr in module __builtin__:

getattr(...)
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.
(END)

getattr(),顾名思义就是获取对象的属性,getattr(x, 'y')等价于 x.y。 第三个参数可有可无,当给getattr()第三个参数时,如果对应的属性不存在,它会作为返回值返回。
看下面代码:
class Test(object):
val = 1

>>> Test.val
1
>>> getattr(Test, 'val')
1
>>> getattr(Test, 'va', 5)
5

因为val是Test的属性,所以通过getattr可以获取到val的值,而va则不是Test的属性,但我们传进了第三个参数5,所以返回5。


使用 内建函数dir()可以查看一个对象的属性,如下
>>> dir(Test)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'val']

再看看下面的例子:
dir1 = {}
dir1['a'] = 1
dir2['b'] = 2
>>> getattr(dir1, 'a')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'dict' object has no attribute 'a'


但为什么通过getattr获取不了dir1['a']的值呢?根据解释器的错误信息就可以看出dir1没有名为‘a'的属性。
再使用dir(dir1)来看下

>>> dir(dir1)
['__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', 'viewitems', 'viewkeys', 'viewvalues']

 

dir1的确没有'a'这个属性,但是有__str__这个属性

>>> getattr(dir1, '__str__')()
"{'a': 1, 'b': 2}"
>>> dir1.__str__()
"{'a': 1, 'b': 2}"

在调用getattr(obj,name)时,如果实例obj没有name属性,则会去调用类中的__getattr__

 

__getattr__
__getattr__()是仅当属性不能在实例的__dict__或它的类(类的__dict__),或父类的__dict__中找到时,才被调用。一般在代码中包含一个对getattr()內建函数的调用
每一个类都会用一个字典,把它包含的属性放到自己的字典里。

 

>>> Test.__dict__
dict_proxy({'__dict__': <attribute '__dict__' of 'Test' objects>, '__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'Test' objects>, '__doc__': None, 'val': 1})


看下面的示例代码
#!/usr/bin/env python


class Test1(object):


def __init__(self, obj):
print "In __init__"
self.data = obj


def __str__(self):
print "In __str__"
return str(self.data)


__repr__ = __str__


def get_attr(self):
print "In getattr"
return self.data


def __getattr__(self, attr):
print "In __getattr__"
return getattr(self.data, attr)


if __name__ == '__main__':
myString = Test1('hello')
print myString
print myString.upper()
print myString.get_attr()


看下输出结果
cullen@cullen--machine:~/python$ ./getattr.py
In __init__
In __str__
hello
In __getattr__
HELLO
In getattr
hello


下面对结果进行简要的分析
myString = Test1('hello')
//输出结果In __init__, 不用解释了吧
print myString
//输出结果
//In __str__
//hello
print myString.upper()
//输出结果
//In __getattr__
//HELLO
重点就在这里,我们的实例myString并没有upper()这个属性,所以myString.upper()等价于getattr(myString.data, upper)()
print myString.get_attr()
//输出结果,因为gets_attr()是myString的属性,所以没有调用__getattr__。
//In getattr
//hello

————————————————
版权声明:本文为CSDN博主「wangyiyan212」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/wangyiyan315/article/details/14229981

posted on 2022-01-21 20:45  guolongnv  阅读(426)  评论(0编辑  收藏  举报