我知道这段代码是正确的:
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
发布于 2009-12-22 15:26:50
Alex的回答很好,但是既然您要求这样做,那么就为您提供一个示例代码:)
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__ to 定义未找到的属性如何处理
和
getattr to get attributes
发布于 2009-12-22 15:14:16
getattr是一个内置函数,它(至少)接受两个参数:从中获取属性的对象和属性的字符串名称。
如果字符串名是一个常量,比如'foo',则getattr(obj, 'foo')的与obj.foo的完全相同。
因此,内置函数getattr的主要用例是属性名不是常量,而是变量。第二个重要的用例是当您向它传递三个参数而不是两个参数时:在这种情况下,如果对象中没有该属性,getattr将返回第三个“默认”参数,而不是引发异常。
__getattr__是类中定义的一种特殊方法,当该类的实例的某些属性被请求时会调用该方法,而提供该属性的其他常规方法(通过实例的__dict__、插槽、属性等)都会失败。例如,当您要将其他未定义的属性查找委托给其他对象时,可以对其进行定义。
所以你的第二个例子是错误的,因为内置的getattr不能通过一个参数来调用。
第三个方法失败了,因为您试图从其中“获取属性”的字典没有该属性--它具有项,当然,这些项与属性完全不相交。
发布于 2009-12-22 15:28:59
__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了!
https://stackoverflow.com/questions/1944625
复制相似问题