Python getattr和getattr之间的关系是什么?

Python getattr和getattr之间的关系是什么?,python,getattr,Python,Getattr,我知道这个代码是正确的: 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')

我知道这个代码是正确的:

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')

我们应该在哪里使用
\uuu getattr\uuu
getattr

getattr
是一个内置函数,包含(至少)两个参数:从中获取属性的对象和属性的字符串名称

如果字符串名称是一个常量,比如说
'foo'
getattr(obj,'foo')
obj.foo
完全相同

因此,内置函数
getattr
的主要使用情形是,属性名不是常量,而是变量。第二个重要的用例是当您向它传递三个参数时,而不仅仅是两个参数:在这种情况下,如果对象中缺少属性,
getattr
返回第三个“default”参数,而不是引发异常


\uuuuu getattr\uuuuuuu
是一种特殊的方法,在类中定义,当请求该类实例的某个属性时会调用该方法,而提供该属性的其他常规方法(通过实例的
\uuuuuuu dict\uuuuuuuuu
、插槽、属性等)都失败。例如,当您希望将其他未定义的属性查找委托给其他对象时,可以定义它

因此,您的第二个示例是错误的,因为内置的
getattr
可以从不使用单个参数调用


第三个失败是因为您试图从中“获取属性”的词典没有该属性——它有项,当然这些项与属性完全不相交。

Alex的回答很好,但提供了一个示例代码,因为您需要它:)

简言之,答案是

你用

\uuuu getattr\uuuu
定义如何处理未找到的属性

getattr
toget属性

\uuuu getattr\uuuu()
是一个可以定义的特殊方法函数。当成员查找失败时,将调用此函数

getattr()
是一个可以调用以尝试成员查找的函数。如果查找成功,则获得成员(可能是方法函数对象,也可能是数据属性对象)
getattr()
也可以在查找失败的情况下返回默认值

如果您声明一个
\uuu getattr\uuuu()
成员函数,您可以让它有时成功,也可以让它每次都成功

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还有
\uuuu 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

虽然你的答案很好,@zjm1126想要一个代码示例,因为他的英语不太好。+1因为他提到了getattribute,我猜这个问题实际上是关于它的。getattribute的简单解释很好,我一直觉得不清楚。如果你使用
\uuuu getattr\uuuu
,请小心,因为它会破坏内置模块的
副本,除非你为你的班级实施
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。我花了一些时间来追踪这只虫子。。。无论如何,在2.7版本中,@Trilarion的可能副本不是该问题的正确副本
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__'"