2013-02-02 65 views
0

考慮一下:獲得所有屬性到達從一個模塊或其它任何物體

>>> import math 
>>> dir(math) 
['__doc__', '__name__', '__package__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e', 'exp', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'hypot', 'isinf', 'isnan', 'ldexp', 'log', 'log10', 'log1p', 'modf', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc'] 

__dict__沒有列出,但我仍然可以做

>>> math.__dict__ 

同樣的事情

>>> class MyClass(object): 
     def __init__(self, var1, var2): 

      self.a = var1 
      self.b = var2 

     def __call__(self, arg): 

      print " The arg passed is ", arg 

>>> dir(MyClass) 

['__call__', '__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__'] 

__bases____base__未列出,但我仍可以這樣做:

>>> MyClass.__bases__ 
(<type 'object'>,) 
>>> MyClass.__base__ 
<type 'object'> 

問:

我怎麼能知道或者提前告訴從Python對象可到達的所有屬性?在這種情況下,我怎麼能告訴math模塊有__dict__MyClass__base____bases__

+2

'dir(type(MyClass))'會顯示它們。 Metaclass屬性通常對'dir'隱藏。與'Myclass.mro()'同樣的事情。 – JBernardo

+0

順便說一句,你可以定義你自己的'__dir__'方法,並返回隨機的名字,如果你想... – JBernardo

+0

@JBernardo什麼是mro()? – abc

回答

2

如果您正在尋找完全一般的東西,則無法執行此操作,因爲屬性查找是動態的。正如the docs所說:

嘗試返回該對象的有效屬性列表。

關鍵詞有「企圖」。下面:

注意由於dir()主要作爲交互提示使用的便利提供,因此它試圖提供一組有趣的名稱,而不是試圖提供一組嚴格或一致定義的名稱,其詳細行爲可能會在各版本中發生變化。例如,當參數是一個類時,元類屬性不在結果列表中。

實際上,它所能做的就是查看對象的__dict__,它的類型以及該類型的任何基類。 (然後它會減少一些東西 - 例如,類型的屬性被跳過以避免暴露元類屬性,這通常不關心)。如果您需要確切的詳細信息,請閱讀上面鏈接的文檔。

同時,如果對象具有__getattr__/__setattr__/__delattr__,或__getattribute__,或C-API上述的當量,它可以具有不在任何字典,甚至無限集合其中所有種屬性。例如:

class C(object): 
    def __getattr__(self, name): 
     return name 
c = C() 
print(c.a) 

這將打印出a。但是dir怎麼可能知道c.a存在?即使它可以解釋我的代碼,它也必須列出所有可能的字符串列表,而這些字符串顯然不是你想要的。

還有一些特殊的屬性名稱在解釋器的封面下以特別的方式處理。

此外,任何對象都可以定義一個__dir__方法來返回任何它想要的。

如果你正在尋找特定的東西,你可以做到這一點。例如,如果您只是試圖在不減去元類屬性的情況下獲取屬性,那只是dir(x) + dir(type(x)),或者可能更好,dir(x) + [a for a in dir(type(x)) if a not in dir(x)](以刪除重複項)。

但是,如果你想知道一個對象的所有屬性,那麼你不能。

+0

很好的解釋!非常感謝。 – abc

+1

如果您對此有興趣,請閱讀[自定義屬性訪問](http://docs.python.org/2/reference/datamodel.html#customizing-attribute-access),特別是關於描述符和插槽的部分,然後閱讀元類(2.x和3.x中文檔的不同部分)。如果你瞭解了這一點,你就可以得到一個關於Python中大部分「魔術」真正起作用的心理模型。 – abarnert

相關問題