以下代码在Python 2和Python 3中的行为有所不同,我不确定原因。
class Dataset(object):
def __getattr__(self, item):
if not item in dir(self):
print(item)
a = Dataset()
a.Hello
Python 3中的结果:
> Hello
Python 2中的结果:
__members__
__members__
__methods__
...
无限制地直到达到递归上限。 “dir”的行为有什么不同?
编辑:有解决方法吗? self。 dict 是显而易见的选择,但它不包含在我的代码中成为问题的函数。
答案 0 :(得分:6)
Python 2.7和3.5中dir
的文档似乎相同 - 没有实现细节。但显然,Python 2中的dir()
会调用__getattr__
来导致无限递归。
但是,两个文档集都说
因为dir()主要是为了方便在交互式提示中使用而提供的,所以它试图提供一组有趣的名称而不是试图提供严格或一致定义的名称集,并且其详细行为可能会改变跨版本。例如,当参数是类时,元类属性不在结果列表中。
关于它是一种便利的说明非常重要。
如果您修改__getattr__
以查看self.__dict__
而非使用dir()
,则问题就会消失。
In [5]: class Dataset(object):
def __getattr__(self, item):
if not item in self.__dict__:
print(item)
...:
In [6]: a = Dataset()
In [7]: a.Hello
Hello
答案 1 :(得分:3)
在不检查源代码的情况下,我不能说为什么会发生这种情况(尽管我有一些假设),但这是一个非常简单的解决方法:
class Dataset(object):
def __getattr__(self, item):
try:
super(Dataset, self).__getattr__(item)
except AttributeError:
print(item)
答案 2 :(得分:1)
不需要检查if not item in dir(self)
def __getattr__
如果项目在dir(自我)中列出,则 __getattr__
不会被调用
您可以将代码设为
class Dataset(object):
x = 12
def __getattr__(self, item):
print(item)
a = Dataset()
a.Hello # print Hello
a.x # return 12