区别于;dir";在Python2和Python3之间

区别于;dir";在Python2和Python3之间,python,Python,以下代码在Python2和Python3中的行为不同,我不知道为什么 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__

以下代码在Python2和Python3中的行为不同,我不知道为什么

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是一个明显的选择,但它不包括在我的代码中出现问题的函数。

如果不检查源代码,我无法说明为什么会发生这种情况(尽管我有一些假设),但这里有一个非常简单的解决方法:

class Dataset(object):
    def __getattr__(self, item):
        try:
            super(Dataset, self).__getattr__(item)
        except AttributeError:
            print(item)

Python2.7和3.5中的
dir
文档似乎是相同的-没有实现细节。但是很明显,Python2中的
dir()
调用了
\uu getattr\uuu
,导致了无限递归

然而,两个文档集都这么说

由于提供dir()主要是为了方便在交互提示下使用,因此它尝试提供一组有趣的名称,而不是提供严格或一致定义的名称,其详细行为可能会在不同版本中发生变化。例如,当参数是类时,元类属性不在结果列表中

关于这是一种方便的注意是很重要的

如果您修改
\uuuu getattr\uuuuuuuuuu
以查看
self.\uuuuu dict\uuuuuuuuuu
而不是使用
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

不需要检查目录(self)中是否有

如果项目列在目录(self)中,则不会调用 您可以将代码设置为

class Dataset(object):
    x = 12
    def __getattr__(self, item):
        print(item)

a = Dataset()
a.Hello  # print Hello
a.x      # return 12

实际上,如果属性已经存在,
\uuuuu getattr\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。由于该代码不存在,因此调用了
\uu getattr\uuu()
。它调用
dir()
。。。