我知道这段代码是对的:
class A:
def __init__(self):
self.a = 'a'
def method(self):
print "method print"
a = A()
print getattr(a, 'a', 'default')
print getattr(a, 'b', 'default')
print getattr(a, 'method', 'default')
getattr(a, 'method', 'default')()
这是错误的:
# will __getattr__ affect the getattr?
class a(object):
def __getattr__(self,name):
return 'xxx'
print getattr(a)
这也是错误的:
a={'aa':'aaaa'}
print getattr(a,'aa')
我们应该在哪里使用__getattr__
和getattr
?
答案 0 :(得分:51)
亚历克斯的答案很好,但是在你提出要求后为你提供示例代码:)
class foo:
def __init__(self):
self.a = "a"
def __getattr__(self, attribute):
return "You asked for %s, but I'm giving you default" % attribute
>>> bar = foo()
>>> bar.a
'a'
>>> bar.b
"You asked for b, but I'm giving you default"
>>> getattr(bar, "a")
'a'
>>> getattr(bar, "b")
"You asked for b, but I'm giving you default"
所以简短的回答是
您使用
__getattr__
到定义如何处理找不到的属性
和
getattr
获取 属性
答案 1 :(得分:37)
getattr
是一个带有(至少)两个参数的内置函数:从中获取属性的对象,以及属性的字符串名称。
如果字符串名称是常量,例如'foo'
,getattr(obj, 'foo')
与obj.foo
完全相同。
因此,内置函数getattr
的主要用例是当您没有将属性名称作为常量,而是作为变量。第二个重要的用例是当你传递三个参数而不是两个时:在这种情况下,如果对象中没有该属性,getattr
将返回第三个“默认”参数,而不是异常。
__getattr__
是一个特殊的方法,在类中定义,在请求该类的实例的某个属性时调用,以及提供该属性的其他常规方法(通过实例的__dict__
全部失败,插槽,属性等等。您可以定义它,例如,当您要将其他未定义的属性查找委托给其他对象时。
所以你的第二个例子是错误的,因为内置getattr
可以从不用一个参数调用。
第三个失败是因为您尝试“获取属性”的字典没有该属性 - 它具有项,当然这与属性完全不相交。
答案 2 :(得分:17)
__getattr__()
是您可以定义的特殊方法函数。当成员查找失败时,将调用此函数。
getattr()
是您可以调用以尝试成员查找的函数。如果查找成功,则获取成员(可能是方法函数对象,或者可能是数据属性对象)。在查找失败的情况下,getattr()
也可以返回默认值。
如果你宣布一个__getattr__()
成员函数,你可以让它有时成功,或者你可以每次都成功。
class A(object):
def __getattr__(self, name):
return "I pretend I have an attribute called '%s'" % name
a = A()
print a.foo # prints "I pretend I have an attribute called 'foo'"
Python也有__getattribute__()
,每次查找都会始终调用。这非常危险,因为它无法正常访问成员。
class A(object):
def __init__(self, value):
self.v = value
def __getattribute__(self, name):
return "I pretend I have an attribute called '%s'" % name
a = A(42)
print a.v # prints "I pretend I have an attribute called 'v'"
print a.__dict__["v"] # prints "I pretend I have an attribute called '__dict__'"
糟糕,现在无法访问a.v!