python - python GC是否保证是一个引用计数垃圾收集器
问题描述
对于我的存储库类,我在函数需要时创建与数据库的连接(如果没有)。如果不是无,我正在使用__del__
关闭连接。该对象保证是短暂的。
我意识到我依赖 Ref 计数来尽快关闭连接。我需要连接成为课堂上的一个字段,因为我正在做一个select for update
. 我阅读的默认 python gc 确实至少计算了 CPython 实现。但是 pypy 实现有许多不同类型的垃圾收集器。靠 ref 计数 gc 尽快关闭连接可以吗?或者我应该编写一个单独的函数并确保使用 try finally 块关闭连接?
该类仅包含连接字段和两个函数,一个用于锁定数据库中的表并选择值,另一个用于更新它们。
这是我目前的实现:
class ReserveRepository:
def __init__(self):
self.conn = None
def select(self):
cur = None
try:
self.conn = psycopg2.connect(config.DATABASE_URL)
cur = self.conn.cursor()
cur.execute('lock table sometable in ACCESS EXCLUSIVE mode')
cur.execute('select id from sometable where condition')
return list(map(lambda x: x[0]))
finally:
if cur is not None:
cur.close()
def update_quantities(self, id):
cur = None
try:
if self.conn is None:
self.conn = psycopg2.connect(config.DATABASE_URL)
cur = self.conn.cursor()
cur.execute('update sometable set column1 = value where id = %s', (id,))
self.conn.commit()
return reservation_id
finally:
if cur is not None:
cur.close()
def __del__(self):
if self.conn is not None:
self.conn.close()
self.conn = None
解决方案
tldr; 答案是否定的。据我了解,Pypy 没有实现引用计数。为了证明这一点,我做了这个简单的程序:
class Test:
def __init__(self):
print('__init__')
def __del__(self):
print('__del__')
t = Test()
print(t)
CPython 3.8.2 上的输出是:
__init__
<__main__.Test object at 0x7f6e3bc13dc0>
__del__
但是,Pypy 7.3.1 (Python 3.6.9) 上的输出是
__init__
<__main__.Test object at 0x00007f58325dfe88>
该__del__
函数未被调用。