1

MySQLDb 使用弱代理来防止游标和连接之间的循环依赖。

但是您会从关于 weakref 的文档中期望您仍然可以测试等效性。然而:

In [36]: interactive.cursor.connection.thread_id()
Out[36]: 4267758

In [37]: interactive.web_logic.conns.primary.thread_id()
Out[37]: 4267758

In [38]: interactive.cursor.connection == interactive.web_logic.conns.primary
Out[38]: False

In [39]: interactive.cursor.connection
Out[39]: <weakproxy at 0x3881c60 to Connection at 0x94c010>

In [40]: interactive.web_logic.conns.primary
Out[40]: <_mysql.connection open to 'xendb01' at 94c010>

如何判断连接是否相同?

4

3 回答 3

3

我早就发现weakref.proxy's 的设计和实现有点不稳定。见证...:

>>> import weakref
>>> ob=set(range(23))
>>> rob=weakref.proxy(ob)
>>> rob==ob
False
>>> rob.__eq__(ob)
True

...绝对奇特!在实践中,我使用的weakref是弱键或弱值字典;但weakref.ref比它上面的代理包装器更健全:

>>> wr=weakref.ref(ob)
>>> wr()==ob
True

不幸的是,需要“调用” ref 来获取对象(如果对象已经消失,则为 None)使其不透明(因此 DB API 模块在保持与 API 兼容的同时无法做到这一点)。我不明白为什么 MySqlDb 想要弱光标-> 连接引用,但如果他们这样做,我明白他们为什么觉得他们必须使用代理而不是引用。然而,人们为这种透明度付出了非常高的代价!

顺便说一句,“显式__eq__”技巧(或等效的技巧__cmp__,取决于底层对象的类型)可能会对您有所帮助,即使它绝对不优雅!

于 2009-08-26T01:58:41.577 回答
1

Wrap the non proxy with weakref.proxy and use the identity operator:

>>> interactive.cursor.connection is weakref.proxy(interactive.web_logic.conns.primary)
True

Calling weakref.proxy() twice will return the same proxy object.

于 2009-08-26T03:54:22.817 回答
0

如果对象是标准的weakref,则需要调用它来获取对象本身。

import weakref
class Test(object): pass
a = Test()
b = weakref.ref(a)
a is b() # True
a == b() # True

但是,在这里使用weakrefs 似乎是错误的:如果我构造一个连接,从中创建一个游标,然后丢弃连接对象,则游标应该保持有效。除非连接保留所有游标的列表,否则不应该存在循环依赖关系,在这种情况下这应该是弱引用。

于 2009-08-26T00:56:05.023 回答