2012-03-13 105 views
2

dir(x)dir(x.__class__)之間的區別是什麼?後者返回一個不同的屬性列表,但與前者重疊。Python dir(dict)vs dir(dict .__ class__)

例如,SQLAlchemy的sqlalchemy.create_engine()函數會創建一個新的Engine實例。當我打電話dir(engine)(假設engine是VAR指向相應的實例)我得到以下列表中返回:

['__class__', '__delattr__', '__dict__', '__doc__', '__format__', 
'__getattribute__', '__hash__', '__init__', '__module__', '__new__', 
'__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', 
'__str__', '__subclasshook__', '__weakref__', '_connection_cls', '_echo', 
'_execute_clauseelement', '_execute_compiled', '_execute_default', 
'_execution_options', '_has_events', '_run_visitor', '_should_log_debug', 
'_should_log_info', 'connect', 'contextual_connect', 'create', 'dialect', 
'dispatch', 'dispose', 'driver', 'drop', 'echo', 'engine', 'execute', 'func', 
'has_table', 'logger', 'logging_name', 'name', 'pool', 'raw_connection', 
'reflecttable', 'run_callable', 'scalar', 'table_names', 'text', 'transaction', 
'update_execution_options', 'url'] 

調用dir(engine.__class__)結果如下:

['__class__', '__delattr__', '__dict__', '__doc__', '__format__', 
'__getattribute__', '__hash__', '__init__', '__module__', '__new__', 
'__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', 
'__str__', '__subclasshook__', '__weakref__', '_connection_cls', 
'_execute_clauseelement', '_execute_compiled', '_execute_default', 
'_execution_options', '_has_events', '_run_visitor', '_should_log_debug', 
'_should_log_info', 'connect', 'contextual_connect', 'create', 'dispatch', 
'dispose', 'driver', 'drop', 'echo', 'execute', 'func', 'has_table', 
'logging_name', 'name', 'raw_connection', 'reflecttable', 'run_callable', 
'scalar', 'table_names', 'text', 'transaction', 'update_execution_options'] 

有這兩個結果之間的重疊,但也有差異,我沒有發現任何在解釋差異和原因的文檔中特別有用的東西。

回答

6

粗略地,dir(instance)列出了實例屬性,類屬性和所有基類的屬性。 dir(instance.__class__)僅列出類屬性,所有基類的屬性。

使用dir()時,要記住一個重要的事情是從documentation這樣一個字條:

因爲dir()作爲使用的便利性,在一個互動的提示,主要提供,它試圖提供一套有趣的名稱超過它試圖提供嚴格或一致定義的名稱集合,並且其詳細行爲可能會在不同版本之間發生變化。例如,當參數是一個類時,元類屬性不在結果列表中。

+0

Upvote爲「有趣的一組名稱」部分。 – kindall 2012-03-13 22:47:27

2

的差異應該是不言自明的:在一個情況下,你所要求的一個實例的dir(),而在其他情況下,你所要求的是充當其模板類的dir()。通過在__init__()方法中創建實例,實例可能具有不屬於該類的屬性。

class Foo(object): 
    def __init__(self): 
     self.answer = 42 

f = Foo() 
set(dir(f)) - set(dir(Foo)) 
>>> set(['answer']) 

實例屬性用於存儲特定於某個實例的數據。類屬性存儲由該類的所有實例共享的數據,或者有時由該類本身使用。方法是一種特殊情況,因爲它們實際上存儲在兩個地方(它們在類中定義,但稍後綁定到每個實例)。

+0

「[方法]在創建時綁定到實例」。我不認爲綁定方法是在屬性訪問時創建的,而不是在創建實例時創建的。 (再次,我認爲你的答案比我的更容易閱讀。) – 2012-03-13 22:37:56

+0

嗯,這是一個有趣的細節! – kindall 2012-03-13 22:45:59

+0

@SvenMarnach:你的答案沒有錯! – kindall 2012-03-13 23:08:58