【问题标题】:Why I cannot build a chain of methods? (method1.method2.method3)为什么我不能建立一个方法链? (方法1.方法2.方法3)
【发布时间】:2009-09-26 21:46:49
【问题描述】:

如果我有以下代码:

import sqlite
sqlite.connect('tmp.db').cursor().close()

我收到以下错误消息:

Traceback (most recent call last):
  File "searchengine2.py", line 13, in ?
    sqlite.connect('tmp.db').cursor().close()
  File "/usr/lib64/python2.4/site-packages/sqlite/main.py", line 280, in close
    if self.con and self.con.closed:
ReferenceError: weakly-referenced object no longer exists

但是,如果我按以下方式修改代码:

import sqlite
x1 = sqlite.connect('tmp.db')
x2 = x1.cursor()
x3 = x2.close()

一切都很好。为什么?

【问题讨论】:

    标签: python sqlite methods


    【解决方案1】:

    显然cursor 保持对连接的弱引用 (self.con)。因为您链接了函数,所以您实例化的连接在您实例化游标后立即超出范围 - 没有任何东西持有对连接的 strong 引用,并且该连接有资格进行垃圾回收.

    因此,当您尝试close 游标(它又尝试close 连接)时,该连接已经超出范围并且可能已被垃圾回收——如果是,那么连接已关闭。

    如果不修改光标的源以使其具有对连接的强引用,则无法解决此问题,并且没有简单的方法来判断如果这样做可能会引入多少问题。 (好)设计师不会在没有充分理由的情况下随意做出弱引用。

    (希望你能理解来自your last question 的弱引用。)

    【讨论】:

    • @Mark,很好的诊断,但是转移到弱引用的选择在 pysqlite 发行说明的历史中有很好的记录:非常简单,游标曾经对连接有强引用,但当然有时保持连接不符合程序员的意愿,因此决定使用弱引用来代替——这并不神秘;-)。
    • 我实际上并没有查找任何关于为什么/是否使用弱引用的硬数据。感谢您证实我的怀疑:)
    【解决方案2】:

    看起来cursor() 返回(并保留)对连接的弱引用,因此,当对连接的强引用离开调用堆栈时,您的连接(connect() 的结果)被留下没有任何强引用。因此,当调用 close() 时,您的连接已被破坏。

    第二种形式通过始终保持对您的联系的强烈引用来避免这种情况。

    【讨论】:

      猜你喜欢
      • 2013-10-05
      • 1970-01-01
      • 2023-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-06
      • 2016-10-24
      相关资源
      最近更新 更多