2011-01-18 17 views
15

如果我想訪問一個對象的實例變量列表,我可以撥打myObject.__dict__.keys()。我想使用這個屬性來打印出一個對象的所有實例變量。我很猶豫,因爲__dict__是一個「祕密」屬性,我不明白什麼this footnote意味着什麼。使用__dict訪問Python實例變量__-它錯了嗎?

那麼使用myObject.__dict__是錯的嗎?

+4

你可能(?)更喜歡'vars(myObject)'的風格,但這與你的問題是正交的。它給出了相同的__dict__。 –

回答

6

腳註的含義是,您不應該直接嘗試訪問__dict__,而是檢查您想要的功能/行爲是否可用。的

因此,而不是做這樣的事情:

if "__some_attribute__" in obj.__dict__: 
    # do stuff 

則應該這樣做:

try: 
    obj.some_action_i_want_to_do(...) 
except AttributeError: 
    # doesn't provide the functionality I want 

造成這種情況的原因是因爲不同的對象可能會提供不同的內部參考一定作用,但仍提供所需的輸出。

如果你想列出「內部」爲了調試和檢查當前對象,那麼dir()是正確的方法。

+0

但'dir()'只給出名稱; '__dict__'也給對象本身。 –

-2

根據該腳註,__dict__僅存在於模塊對象上。

你在找什麼可能是內置的dir()功能。例如:

>>> f = open('foo', 'w') 
>>> dir(f) 
['__class__', '__delattr__', '__doc__', '__enter__', '__exit__', '__format__', '__getattribute__', '__hash__', '__init__', '__iter__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'close', 'closed', 'encoding', 'errors', 'fileno', 'flush', 'isatty', 'mode', 'name', 'newlines', 'next', 'read', 'readinto', 'readline', 'readlines', 'seek', 'softspace', 'tell', 'truncate', 'write', 'writelines', 'xreadlines'] 
+0

'__dict__' * does *存在於模塊之外的東西。雖然它不存在所有對象(內置函數,帶'__slots__'的東西,也許是舊式的類實例?)。 – delnan

3

將它用於諸如打印出用於調試的成員應該沒問題。但如果這就是你所做的一切,看看漂亮的打印。

http://docs.python.org/library/pprint.html

的主要問題__dict__,是它違反了Python有對象的隱含可見性規則。

+0

'__dict__'是hackery。它強大而且危險,你根本不需要編程。這就是爲什麼。它違反了知名度只是其中的一部分。 – delnan

+0

感謝您指出pprint。我總是想知道是否有一種簡單的方法來模擬iPython風格的集合打印。 – sans

+0

這個'__dict__'問題看起來有點像兔子洞,但我想更好地理解它。隱含的能見度規則是什麼意思? – sans

5

該腳註參照模塊__dict__屬性。對象的__dict__屬性不帶此類警告(documentation)。

+0

使用訪問器,元類或插槽時,對象有類似的警告。 Python中的異常非常便宜,以至於它們用於結束生成器中的迭代。 – Apalala