为什么weakproxy在python中并不总是保持等价性?

为什么weakproxy在python中并不总是保持等价性?,python,weak-references,Python,Weak References,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 == in

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>
[36]中的
:interactive.cursor.connection.thread\u id()
Out[36]:4267758
[37]:interactive.web\u logic.conns.primary.thread\u id()
Out[37]:4267758
在[38]中:interactive.cursor.connection==interactive.web\u logic.conns.primary
Out[38]:假
In[39]:interactive.cursor.connection
出[39]:
在[40]中:interactive.web\u logic.conns.primary
出[40]:

如何判断连接是否相同?

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

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

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

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

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

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

我早就发现
weakref.proxy
的设计和实现有些不稳定。证人…:

>>> 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来获取对象(或者如果对象从此消失,则不需要),这使得对象不透明(因此DB API模块在保持与API兼容的同时无法做到这一点)。我不明白为什么MySqlDb想要弱游标->连接引用,但如果他们想要,我明白为什么他们觉得必须使用代理而不是引用。然而,人们为这种透明度付出了高昂的代价


顺便说一句,“显式
\uuuuu eq\uuuu
”技巧(或具有
\uuuuu cmp\uuuuu
的等效技巧,取决于底层对象的类型)可能会对您有所帮助,即使它肯定不雅观

我一直发现
weakref.proxy
的设计和实现有些不稳定。证人…:

>>> 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来获取对象(或者如果对象从此消失,则不需要),这使得对象不透明(因此DB API模块在保持与API兼容的同时无法做到这一点)。我不明白为什么MySqlDb想要弱游标->连接引用,但如果他们想要,我明白为什么他们觉得必须使用代理而不是引用。然而,人们为这种透明度付出了高昂的代价


顺便说一句,“显式
\uuuuu eq\uuuu
”技巧(或具有
\uuuuu cmp\uuuuu
的等效技巧,取决于底层对象的类型)可能会对您有所帮助,即使它肯定不雅观

使用weakref.proxy包装非代理并使用identity运算符:

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

调用weakref.proxy()两次将返回相同的代理对象。

使用weakref.proxy包装非代理并使用标识运算符:

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

调用weakref.proxy()两次将返回相同的代理对象。

它是weakproxy,而不是weakref。也许是weakproxy实现中的一个弱点?哦,你是指weakref.proxy(不是“weakproxy”,至少不是在Python标准库中)。这似乎没有公开任何方法来检索原始对象,这似乎是该类型的一个主要限制。这必须是一种疏忽;这种限制似乎完全没有必要。甚至似乎没有任何方法可以确定对象是否是代理(除了尝试解析obj.\uu str\uuu())。这种类型似乎没有完全充实。也就是说,请尝试“obj1.\uu dict\uuuuuuuuuu”是obj2.\uu dict\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuj”。(“你每30秒只能发表一条评论。”这个网站偶尔会让人恼火。)是的,我从str表示和阅读c代码中得到了“weakproxy”。但看来weakref.proxy是真正创建它的唯一方法。它是一个weakproxy,而不是一个weakref。也许是weakproxy实现中的一个弱点?哦,你是指weakref.proxy(不是“weakproxy”,至少不是在Python标准库中)。这似乎没有公开任何方法来检索原始对象,这似乎是该类型的一个主要限制。这必须是一种疏忽;这种限制似乎完全没有必要。甚至似乎没有任何方法可以确定对象是否是代理(除了尝试解析obj.\uu str\uuu())。这种类型似乎没有完全充实。也就是说,请尝试“obj1.\uu dict\uuuuuuuuuu”是obj2.\uu dict\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuj”。(“你每30秒只能发表一条评论。”这个网站偶尔会让人恼火。)是的,我从str表示和阅读c代码中得到了“weakproxy”。但看来weakref.proxy是真正创建它的唯一方法。我一直认为proxy在幕后使用了一些非常丑陋的破坏抽象的魔法,以避免调用ref之类的函数。现在我知道了。你的“特定”比较结果是因为set。eq不知道代理。它看到另一个对象不是集合,因此返回False。rob.\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。这是一个没有好的解决办法的疣。(选项是要么对weakref.proxy的实例进行set和其他类型的检查,要么在调用eq之前让python解释器透明地替换它。)@Matthew:不完全是,
rob==ob
ob==rob
ar