以下是使用MySQLdb 1.2.3的python 2.7.
我需要一个类包装器来为不支持它的对象添加一些属性(带有__slots__
和/或用C语言编写的类的类)所以我得到了类似这样的东西:
class Wrapper(object): def __init__(self, obj): self._wrapped_obj = obj def __getattr__(self, obj): return getattr(self._wrapped_obj, attr)
我期待dir()
在我的实例上调用的内置Wrapper
函数应该只返回object plus继承的名称wrapped_obj
,并且我发现大多数情况下都是这种情况,但并非所有情况都是如此.我尝试使用自定义旧样式类,自定义新样式类和一些内置类,它总是以这种方式工作:我发现的唯一例外是当包装对象是类的实例时_mysql.connection
.在这种情况下,dir()
我的对象碰巧也知道附加到包装的连接对象的所有方法名称.
我在python文档中读到了dir
,这种行为似乎是合法的:dir
应该返回一个"有趣的名字"列表,而不是实例的"真实"内容.但我真的无法弄清楚它是如何做到的:它实际上理解我的实现__getattr__
并解析为附加项目?如果这是真的,为什么只有那个connection
类而不是更简单dict
?
这里有一些粘贴的代码作为这种奇怪行为的一个例子:
>>> from _mysql import connection >>> c = connection(**connection_parameters) >>> c <_mysql.connection open to '127.0.0.1' at a16920> >>> >>> dir(c) ['affected_rows', 'autocommit', 'change_user', 'character_set_name', 'close', 'commit', 'dump_debug_info', 'errno', 'error', 'escape', 'escape_string', 'field_count', 'get_character_set_info', 'get_host_info', 'get_proto_info', 'get_server_info', 'info', 'insert_id', 'kill', 'next_result', 'ping', 'query', 'rollback', 'select_db', 'set_character_set', 'set_server_option', 'shutdown', 'sqlstate', 'stat', 'store_result', 'string_literal', 'thread_id', 'use_result', 'warning_count'] >>> >>> w = Wrapper(c) >>> dir(w) ['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattr__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_wrapped_obj', 'affected_rows', 'autocommit', 'change_user', 'character_set_name', 'close', 'commit', 'dump_debug_info', 'errno', 'error', 'escape', 'escape_string', 'field_count', 'get_character_set_info', 'get_host_info', 'get_proto_info', 'get_server_info', 'info', 'insert_id', 'kill', 'next_result', 'ping', 'query', 'rollback', 'select_db', 'set_character_set', 'set_server_option', 'shutdown', 'sqlstate', 'stat', 'store_result', 'string_literal', 'thread_id', 'use_result', 'warning_count'] >>> >>> d = Wrapper({}) >>> dir(d) ['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattr__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_wrapped_obj'] >>>
Martijn Piet.. 12
Python 2中有两个不推荐使用的属性,object.__members__
并且object.__methods__
; 这些旨在支持dir()
扩展类型(C定义的对象):
object.__methods__
自2.2版以来不推荐使用:使用内置函数dir()
获取对象属性的列表.此属性不再可用.
object.__members__
自2.2版以来不推荐使用:使用内置函数dir()获取对象属性的列表.此属性不再可用.
这些已从Python 3中删除,但因为您的连接对象(至少在您使用的旧版本中)仍提供通过您的钩子__methods__
找到并在此处使用的属性.__getattr__
dir()
如果print
向__getattr__
方法添加语句,您将看到要访问的属性:
>>> class Wrapper(object): ... def __init__(self, obj): ... self._wrapped_obj = obj ... def __getattr__(self, obj): ... print 'getattr', obj ... return getattr(self._wrapped_obj, attr) ... >>> dir(Wrapper({})) getattr __members__ getattr __methods__ ['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattr__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_wrapped_obj']
对于新样式的对象,只有在类型上正确查找支持的较新__dir__
方法,dir()
因此您不会在此处看到要访问的对象.
该项目历史文件显示属性的大的Python 3兼容性更新被拆除的1.2.4 Beta 1中.
Python 2中有两个不推荐使用的属性,object.__members__
并且object.__methods__
; 这些旨在支持dir()
扩展类型(C定义的对象):
object.__methods__
自2.2版以来不推荐使用:使用内置函数dir()
获取对象属性的列表.此属性不再可用.
object.__members__
自2.2版以来不推荐使用:使用内置函数dir()获取对象属性的列表.此属性不再可用.
这些已从Python 3中删除,但因为您的连接对象(至少在您使用的旧版本中)仍提供通过您的钩子__methods__
找到并在此处使用的属性.__getattr__
dir()
如果print
向__getattr__
方法添加语句,您将看到要访问的属性:
>>> class Wrapper(object): ... def __init__(self, obj): ... self._wrapped_obj = obj ... def __getattr__(self, obj): ... print 'getattr', obj ... return getattr(self._wrapped_obj, attr) ... >>> dir(Wrapper({})) getattr __members__ getattr __methods__ ['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattr__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_wrapped_obj']
对于新样式的对象,只有在类型上正确查找支持的较新__dir__
方法,dir()
因此您不会在此处看到要访问的对象.
该项目历史文件显示属性的大的Python 3兼容性更新被拆除的1.2.4 Beta 1中.