python __getattr__ 和 getattr 是什么关系?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1944625/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the relationship between __getattr__ and getattr?
提问by zjm1126
I know this code is right:
我知道这段代码是正确的:
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')()
And this is wrong:
这是错误的:
# will __getattr__ affect the getattr?
class a(object):
def __getattr__(self,name):
return 'xxx'
print getattr(a)
This is also wrong:
这也是错误的:
a={'aa':'aaaa'}
print getattr(a,'aa')
Where should we use __getattr__
and getattr
?
我们应该在哪里使用__getattr__
和getattr
?
回答by Kimvais
Alex's answer was good, but providing you with a sample code since you asked for it :)
亚历克斯的回答很好,但是因为您要求它为您提供示例代码:)
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"
So in short answer is
所以简而言之
You use
你用
__getattr__
to definehow to handle attributes that are not found
__getattr__
以确定如何处理的属性没有找到
and
和
getattr
to getthe attributes
getattr
要获得的属性
回答by Alex Martelli
getattr
is a built-in function taking (at least) two arguments: the object from which you're getting the attribute, and the string name of the attribute.
getattr
是一个带有(至少)两个参数的内置函数:从中获取属性的对象,以及属性的字符串名称。
If the string name is a constant, say 'foo'
, getattr(obj, 'foo')
is exactly the same thingas obj.foo
.
如果字符串名称是恒定的,也就是说'foo'
,getattr(obj, 'foo')
是完全一样的东西的obj.foo
。
So, the main use case for the built-in function getattr
is when you don't have the attribute name as a constant, but rather as a variable. A second important use case is when you pass it three arguments, rather than just two: in that case, if the attribute is absent from the object, getattr
returns the third, "default", argument, rather than raising an exception.
因此,内置函数的主要用例getattr
是当您没有将属性名称作为常量,而是将其作为变量时。第二个重要的用例是当你传递三个参数而不是两个参数时:在这种情况下,如果属性不存在于对象中,则getattr
返回第三个“默认”参数,而不是引发异常。
__getattr__
is a special method, defined in a class, that gets invoked when some attribute of an instance of that class is requested, and other normal ways to supply that attribute (via the instance's __dict__
, slots, properties, and so on) all failed. You can define it, for example, when you want to delegate otherwise-undefined attribute lookups to other objects.
__getattr__
是在类中定义的特殊方法,当请求该类实例的某些属性时调用该方法,而其他提供该属性的正常方法(通过实例的__dict__
、槽、属性等)都失败了。例如,当您想将其他未定义的属性查找委托给其他对象时,您可以定义它。
So your second example is wrong because the builtin getattr
can neverbe called with a single argument.
所以,你的第二个例子是错误的,因为内置getattr
可从来没有与一个参数调用。
The third one fails because the dictionary you're trying to "get an attribute" from does not have that attribute -- it has items, which are totally disjoint from attributes of course.
第三个失败,因为您试图从中“获取属性”的字典没有该属性——它有items,当然,它们与属性完全不相交。
回答by steveha
__getattr__()
is a special method function that you can define. When a member lookup fails, this function will be called.
__getattr__()
是您可以定义的特殊方法函数。当成员查找失败时,将调用此函数。
getattr()
is a function you can call to attempt a member lookup. If the lookup succeeds, you get the member (perhaps a method function object, or perhaps a data attribute object). getattr()
can also return a default in the case the lookup fails.
getattr()
是一个可以调用以尝试成员查找的函数。如果查找成功,您将获得该成员(可能是一个方法函数对象,或者可能是一个数据属性对象)。 getattr()
也可以在查找失败的情况下返回默认值。
If you declare a __getattr__()
member function, you can make it succeed sometimes, or you can make it succeed every time.
如果你声明了一个__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 also has __getattribute__()
which is alwayscalled on every lookup. It is very dangerous because it can make it impossible to access members normally.
Python 也有__getattribute__()
which总是在每次查找时调用。这是非常危险的,因为它可能导致无法正常访问成员。
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__'"
Oops, it is now impossible to access a.v!
糟糕,现在无法访问 av!