代码之家  ›  专栏  ›  技术社区  ›  rhettg

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

  •  1
  • rhettg  · 技术社区  · 15 年前

    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>
    

    如何判断连接是否相同?

    3 回复  |  直到 15 年前
        1
  •  3
  •   Alex Martelli    15 年前

    我早就发现了 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需要弱游标连接引用,但如果他们需要,我明白为什么他们觉得必须使用代理而不是引用。然而,一个人为这种透明度付出了很高的代价!

    顺便说一句,“明确的 __eq__ “诡计 __cmp__ ,这取决于底层对象的类型)可能会帮助您,即使它绝对不优雅!

        2
  •  1
  •   Matthew Marshall    15 年前

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

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

        3
  •  0
  •   Glenn Maynard    15 年前

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

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

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