Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/358.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
dir()与uu getattr_uu一起执行什么样的python魔术?_Python_Python 2.7 - Fatal编程技术网

dir()与uu getattr_uu一起执行什么样的python魔术?

dir()与uu getattr_uu一起执行什么样的python魔术?,python,python-2.7,Python,Python 2.7,下面是python 2.7和MySQLDB1.2.3中的内容 我需要一个类包装器来为不支持它的对象添加一些属性(带有\uuuu插槽的类和/或一些用C编写的类),所以我得出了如下结论: class Wrapper(object): def __init__(self, obj): self._wrapped_obj = obj def __getattr__(self, obj): return getattr(self._wrapped_obj

下面是python 2.7和MySQLDB1.2.3中的内容

我需要一个类包装器来为不支持它的对象添加一些属性(带有
\uuuu插槽的类和/或一些用C编写的类),所以我得出了如下结论:

class Wrapper(object):

    def __init__(self, obj):
        self._wrapped_obj = obj

    def __getattr__(self, obj):
        return getattr(self._wrapped_obj, attr)
我原以为对我的
Wrapper
实例调用的
dir()
内置函数应该只返回object plus
wrapped\u obj
继承的名称,我发现大多数情况下都是这样,但并非所有情况都是这样。我用一个定制的旧样式类、一个定制的新样式类和一些内置类尝试了这一点,它总是这样工作:我发现的唯一例外是当包装对象是类的实例时
\u mysql.connection
。在本例中,我的对象上的
dir()
碰巧也知道附加到包装连接对象的所有方法名

我在python文档中读到了关于
dir
,这种行为似乎是合法的:
dir
应该返回一个“有趣的名称”列表,而不是实例的“真实”内容。但我真的不明白它是如何做到这一点的:它实际上理解我的
\uuu getattr\uuuu
的实现,并解析为附加项?如果这是真的,为什么只使用该
连接
类,而不使用更简单的
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']
>>> 
来自mysql导入连接的
>>
>>>c=连接(**连接参数)
>>>c
>>> 
>>>处长(c)
[‘受影响的行’、‘自动提交’、‘更改用户’、‘字符集名称’、‘关闭’、‘提交’、‘转储调试信息’、‘错误’、‘转义’、‘转义字符串’、‘字段计数’、‘获取字符集信息’、‘获取主机信息’、‘获取协议信息’、‘获取服务器信息’、‘插入id’、‘杀死’、‘下一个结果’、‘ping’、‘查询’、‘回滚’、‘选择数据库’、‘设置字符’et“,”设置服务器选项“,”关机“,”sqlstate“,”统计“,”存储结果“,”字符串文字“,”线程id“,”使用结果“,”警告计数“]
>>> 
>>>w=包装器(c)
>>>署长(西)
“UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU,”UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU","大小","str","子类钩子","weakref","包装对象","受影响行","自动提交","更改用户","字符集"名称"“,”关闭“,”提交“,”转储调试信息“,”错误“,”转义“,”转义字符串“,”字段计数“,”获取字符集信息“,”获取主机信息“,”获取协议信息“,”获取服务器信息“,”信息“,”插入id“,”杀死“,”下一个结果“,”ping“,”查询“,”回滚“,”选择数据库“,”设置字符集“,”设置服务器选项“,”关机“,”sqlstate“,”存储“,”esult',string\u literal',thread\u id',use\u result',warning\u count']
>>> 
>>>d=包装器({})
>>>署长(丁)
“UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU,”UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU","大小","str","子类钩子","weakref","包装"obj"
>>> 

Python 2中有两个不推荐使用的属性;它们旨在支持扩展类型(C定义的对象)上的
dir()

对象。方法
自版本2.2以来已弃用:使用内置函数
dir()
获取对象属性的列表。此属性不再可用

对象。\uuuu成员\uuuu

自版本2.2以来已弃用:使用内置函数dir()获取对象属性的列表。此属性不再可用

这些属性已从Python 3中删除,但这是因为您的连接对象(至少在您使用的旧版本中)仍然提供了一个
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu方法
属性,该属性可通过
\uuuuuuuuuuuuuuu

如果将
print
语句添加到
\uuu getattr\uuu
方法中,您将看到正在访问的属性:

>>> 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()
支持的较新样式仅在类型上正确查找,因此您不会看到在此处访问该类型


这表明在1.2.4 beta 1的大型Python 3兼容性更新中删除了这些属性。

我无法真实再现您在Python 2.7和MySQLdb上看到的内容
dir(w)
不包括
c
中的名称。您确定没有在包装器上包含返回
dir(self.\u wrapped\u obj)
方法吗?是的,我使用包装器类测试了粘贴的输出,就像上面定义的那样
导入什么;打印mysql.version\u info
生成?
(1,2,3,'final',0)