<p>很晚才去参加派对,但找到了两个很好的资源来更好地解释这一点(IMHO)。</p>
<p>如<a href="http://western-skies.blogspot.com.br/2008/02/complete-example-of-getattr-in-python.html" rel="nofollow noreferrer">here</a>所述,您应该使用<code>self.__dict__</code>从<code>__getattr__</code>中访问字段,以避免无限递归。提供的示例如下:</p>
<blockquote>
<pre><code>def __getattr__(self, attrName):
if not self.__dict__.has_key(attrName):
value = self.fetchAttr(attrName) # computes the value
self.__dict__[attrName] = value
return self.__dict__[attrName]
</code></pre>
</blockquote>
<p>注意:在第二行(上面),一个更像Python的方法是(<code>has_key</code>显然在Python 3中被删除了):</p>
<pre><code>if attrName not in self.__dict__:
</code></pre>
<p><a href="http://farmdev.com/src/secrets/magicmethod/#introducing-getattr" rel="nofollow noreferrer">other resource</a>解释了<code>__getattr__</code>只在对象中找不到属性时调用,并且<code>hasattr</code>如果有<code>__getattr__</code>的实现,则始终返回<code>True</code>。它提供了以下示例来演示:</p>
<blockquote>
<pre><code>class Test(object):
def __init__(self):
self.a = 'a'
self.b = 'b'
def __getattr__(self, name):
return 123456
t = Test()
print 'object variables: %r' % t.__dict__.keys()
#=> object variables: ['a', 'b']
print t.a
#=> a
print t.b
#=> b
print t.c
#=> 123456
print getattr(t, 'd')
#=> 123456
print hasattr(t, 'x')
#=> True
</code></pre>
</blockquote>