好吧,我有点问题,我不太清楚为什么它会以这样的方式发生。我想做的是允许通过python2.7.X中的snake_case或camelCase访问对象上的属性--我认为__getattr__是正确的方法,但显然我错了,我不是前妻
下面是我的简化实现。在这个场景中,无论您访问哪个属性,我都希望返回foo.x。
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如果我这么做了:
f = Foo('myX')
f.x
# => "myX"然而,我不明白为什么:
f.y永远循环。有趣的是,当我把print "__getattr__ called with : %s" % name放在__getattr__的第一行时,当f.y被调用时,getattr(self, 'x')行实际上被调用了,但是看起来并不像getattr实际上是用'x‘来调用的,__getattr__仍然说它是用“y”来调用的。
我一直在环顾四周,我认为这与我对getattr工作方式的误解有关。任何建议或文件,你们都必须指出我将是非常有益的。提前谢谢。
发布于 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属性不存在,等等。
当属性查找没有在通常的位置找到属性时调用(即它不是实例属性,也不是自定义的类树中的属性)。
(这是通过调用
getattr(object, name)并查看它是否引发异常来实现的。)
发布于 2015-05-07 12:03:59
我将发布我在一开始提到的我的snake/camelCase问题的一个工作实现。请查看@Martijn的答案,以了解为什么这种方法有效,而旧的方法失败了。
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, namehttps://stackoverflow.com/questions/30088640
复制相似问题