MySQLdb GImageDerivativeOps.sobel(grey, derivX, derivY, BorderType.EXTENDED);
GImageDerivativeOps.hessianSobel(derivX, derivY, derivXX, derivXY, derivYY, BorderType.EXTENDED);
有一个基本的上下文管理器,可以在 enter 上创建游标,在 exit 上回滚或提交,并且隐式不会禁止异常。来自Connection source:
Connections
那么,有没有人知道为什么光标在退出时没有关闭?
首先,我认为这是因为关闭光标没有做任何事情,并且游标只有一个与Python DB API相关的密切方法(参见对this answer的评论)。但是,事实是关闭光标会烧掉剩余的结果集(如果有),并禁用光标。来自cursor source:
def __enter__(self):
if self.get_autocommit():
self.query("BEGIN")
return self.cursor()
def __exit__(self, exc, value, tb):
if exc:
self.rollback()
else:
self.commit()
在退出处关闭光标会很容易,所以我不得不假设它没有故意完成。另一方面,我们可以看到,当一个游标被删除时,无论如何它都会被关闭,所以我猜垃圾收集器最终会绕过它。我对Python中的垃圾收集知之甚少。
def close(self):
"""Close the cursor. No further queries will be possible."""
if not self.connection: return
while self.nextset(): pass
self.connection = None
另一个猜测是,您可能希望在def __del__(self):
self.close()
self.errorhandler = None
self._result = None
块之后重新使用光标。但我想不出你为什么需要这样做的任何理由。难道你不能总是在其上下文中使用游标,并且只为下一个事务使用单独的上下文吗?
非常清楚,这个例子显然没有意义:
with
应该是:
with conn as cursor:
cursor.execute(select_stmt)
rows = cursor.fetchall()
这个例子也没有意义:
with conn as cursor:
cursor.execute(select_stmt)
rows = cursor.fetchall()
应该是:
# first transaction
with conn as cursor:
cursor.execute(update_stmt_1)
# second transaction, reusing cursor
try:
cursor.execute(update_stmt_2)
except:
conn.rollback()
else:
conn.commit()
同样,在退出时关闭光标会有什么危害,有什么好处不关闭呢?
答案 0 :(得分:10)
直接回答您的问题:在with
区块结束时,我无法看到任何伤害。我不能说为什么在这种情况下没有这样做。但是,由于在这个问题上缺乏活动,我对代码历史进行了搜索,并会对{{strong> 猜测 >提出一些想法{{strong> 猜测 1}} 可以 不被调用:
旋转调用close()
的可能性很小,可能会引发异常 - 可能这已被观察到并被视为不合需要。这可能是newer version of cursors.py
在nextset()
中包含此结构的原因:
close()
可能需要花费一些时间才能完成所有剩余的结果。因此,可能不会调用def close(self):
"""Close the cursor. No further queries will be possible."""
if not self.connection:
return
self._flush()
try:
while self.nextset():
pass
except:
pass
self.connection = None
来避免进行一些不必要的迭代。我认为,你是否认为值得保存这些时钟周期是主观的,但你可以按照“如果没有必要,不要这样做”的方式进行争论。
浏览sourceforge提交时,该功能已于2007年this commit添加到主干中,此后close()
的此部分似乎没有更改。这是基于this commit的合并,其中包含消息
如http://docs.python.org/whatsnew/pep-343.html 中所述,为with语句添加Python-2.5支持请测试
你引用的代码从那时起就没有改变过。
这促使我最后的想法 - 它可能只是第一次尝试/原型刚刚起作用,因此从未改变过。
您链接到旧版连接器的源。我注意到同一个库here有一个更活跃的分支,我在第1点的关于“更新版本”的评论中链接到这个分支。
请注意,此模块的更新版本已在connections.py
内__enter__()
内实施__exit__()
和cursor
:see here。 __exit__()
此处 call self.close()
并且这可能提供了一种使用with语法的更标准方法,例如。
with conn.cursor() as c:
#Do your thing with the cursor
NB 我想我应该添加,据我所知,垃圾收集(不是专家)一旦没有conn
的引用,它将被解除分配。此时将不会引用游标对象,它也将被解除分配。
然而 调用cursor.close()
并不意味着它将被垃圾回收。它只是烧掉结果并将连接设置为None
。这意味着它无法重复使用,但不会立即进行垃圾回收。您可以通过在cursor.close()
阻止后手动调用with
,然后打印cursor
<强> N.B。 2 我认为这是with
语法的一种不寻常的用法,因为conn
对象仍然存在,因为它已经在外部范围内了 - 不像比较常见with open('filename') as f:
with
块结束后没有任何对象与引用挂在一起的<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/blue</item>
<item name="colorButtonNormal">@color/blue</item>
</style>
</resources>
。