簡體   English   中英

Python 2和3之間“dir”的區別

[英]Difference in “dir” between Python 2 and 3

以下代碼在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”的行為有什么不同?

編輯:有解決方法嗎? 自。 dict是顯而易見的選擇,但它不包括在我的代碼中成為問題的函數。

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

沒有檢查源代碼,我不能說為什么會發生這種情況(雖然我有一些假設),但這是一個非常簡單的解決方法:

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

if not item in dir(self)if not item in dir(self)不需要檢查def __getattr__

如果項目在dir(self)中列出,則不會調用__getattr__您可以將代碼作為

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

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM