首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用__getattr__和getattr的无限循环

使用__getattr__和getattr的无限循环
EN

Stack Overflow用户
提问于 2015-05-06 22:17:37
回答 2查看 1.9K关注 0票数 2

好吧,我有点问题,我不太清楚为什么它会以这样的方式发生。我想做的是允许通过python2.7.X中的snake_case或camelCase访问对象上的属性--我认为__getattr__是正确的方法,但显然我错了,我不是前妻

下面是我的简化实现。在这个场景中,无论您访问哪个属性,我都希望返回foo.x

代码语言:javascript
复制
class Foo(object):
  def __init__(self, x):
    self.x = x

  def __getattr__(self, name):
    if hasattr(self, name):
      return getattr(self, name)
    elif hasattr(self, 'x'):
      return getattr(self, 'x')
    else:
      raise AttributeError, n

如果我这么做了:

代码语言:javascript
复制
f = Foo('myX')
f.x             
# => "myX"

然而,我不明白为什么:

代码语言:javascript
复制
f.y

永远循环。有趣的是,当我把print "__getattr__ called with : %s" % name放在__getattr__的第一行时,当f.y被调用时,getattr(self, 'x')行实际上被调用了,但是看起来并不像getattr实际上是用'x‘来调用的,__getattr__仍然说它是用“y”来调用的。

我一直在环顾四周,我认为这与我对getattr工作方式的误解有关。任何建议或文件,你们都必须指出我将是非常有益的。提前谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-05-06 22:20:55

hasattr()是作为对getattr()的调用实现的,如果引发异常,则返回False

只有当您的实例没有该属性时才调用__getattr__;这是一个退步。在hasattr()中使用__getattr__是完全没有意义的。

由于f.x存在,所以从来不调用Foo.__getattr__f.y不存在,因此调用Foo.__getattr__(f, 'y'),它调用hasattr(f, 'y'),后者调用getattr(f, 'y'),后者调用Foo.__getattr__(f, 'y'),因为y属性不存在,等等。

来自 documentation

当属性查找没有在通常的位置找到属性时调用(即它不是实例属性,也不是自定义的类树中的属性)。

来自 function documentation

(这是通过调用getattr(object, name)并查看它是否引发异常来实现的。)

票数 4
EN

Stack Overflow用户

发布于 2015-05-07 12:03:59

我将发布我在一开始提到的我的snake/camelCase问题的一个工作实现。请查看@Martijn的答案,以了解为什么这种方法有效,而旧的方法失败了。

代码语言:javascript
复制
class Foo(object):

def __init__(self, x):
  self.x = x

def __getattr__(self, name):
  #if hasattr(self, name)     # As Martijn pointed out, this call is completely
  #  getattr(self, name)      # useless in this context because the only reason
                              # you are even in __getattr__ is because self
                              # does not have the attribute. This call is what
                              # was causing the infinite loop.
  components = name.split('_')
  camel_case = components[0] + "".join(x.title() for x in components[1:])
  if hasattr(self, camel_case):
    return getattr(self, camel_case)
  else:
    raise AttributeError, name
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30088640

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档