Python dir(dict)vs dir(dict .__ class__)

时间:2012-03-13 22:26:36

标签: python

dir(x)dir(x.__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']

这两个结果之间存在重叠,但也存在差异,我没有在解释差异和原因的文档中找到任何特别有用的东西。

2 个答案:

答案 0 :(得分:6)

粗略地说,dir(instance)列出了实例属性,类属性和所有基类的属性。 dir(instance.__class__)仅列出类属性,即所有基类的属性。

使用dir()时要记住的一件重要事情是来自documentation的注释:

  

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

答案 1 :(得分:2)

差别应该是不言而喻的:在一种情况下,你要求实例的dir(),而在另一种情况下,你要求提供作为其的dir()类模板。通过在__init__()方法中创建实例,实例可能具有不在类中的属性。

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

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

实例属性用于存储特定于某个实例的数据。类属性存储由类的所有实例共享的数据,或者有时由类本身使用。方法是一种特殊情况,因为它们实际上存储在两个地方(它们在类上定义,但稍后绑定到每个实例)。