python GC是否保证是一个引用计数垃圾收集器

python GC是否保证是一个引用计数垃圾收集器,python,garbage-collection,pypy,Python,Garbage Collection,Pypy,对于我的repository类,我在函数需要时创建到数据库的连接(如果没有)。我正在使用\uu del\uu关闭连接(如果没有)。该对象保证是短期的 我意识到我依赖于Ref计数来尽快关闭连接。我需要将连接作为类中的一个字段,因为我正在执行更新选择。我读取的默认pythongc至少对CPython实现进行ref计数。但是pypy实现有许多不同类型的应用程序。依靠ref counting gc尽快关闭连接可以吗?或者我应该编写一个单独的函数,并确保使用try-finally块关闭连接 该类只包含连接

对于我的repository类,我在函数需要时创建到数据库的连接(如果没有)。我正在使用
\uu del\uu
关闭连接(如果没有)。该对象保证是短期的

我意识到我依赖于Ref计数来尽快关闭连接。我需要将连接作为类中的一个字段,因为我正在执行更新选择。我读取的默认pythongc至少对CPython实现进行ref计数。但是pypy实现有许多不同类型的应用程序。依靠ref counting gc尽快关闭连接可以吗?或者我应该编写一个单独的函数,并确保使用try-finally块关闭连接

该类只包含连接字段和两个函数,一个用于锁定数据库中的表并选择值,另一个用于更新值

这是我当前的实现:

class reserverpository:
定义初始化(自):
self.conn=无
def选择(自):
cur=无
尝试:
self.conn=psycopg2.connect(config.DATABASE\u URL)
cur=self.conn.cursor()
cur.execute('lock table sometable in ACCESS EXCLUSIVE mode')
cur.execute('select id from sometable where condition')
返回列表(映射(lambda x:x[0]))
最后:
如果cur不是None:
当前关闭()
def更新_数量(自身、id):
cur=无
尝试:
如果self.conn为无:
self.conn=psycopg2.connect(config.DATABASE\u URL)
cur=self.conn.cursor()
cur.execute('updatesometable set column1=value,其中id=%s',(id,))
self.conn.commit()
返回预定号
最后:
如果cur不是None:
当前关闭()
定义(自我):
如果self.conn不是None:
self.conn.close()
self.conn=无

tldr答案是否定的。据我所知,Pypy没有实现引用计数。为了证明这一点,我制作了一个简单的程序:

类测试:
定义初始化(自):
打印(“初始化”)
定义(自我):
打印(“删除”)
t=测试()
打印(t)
CPython 3.8.2的输出为:

__init__
<__main__.Test object at 0x7f6e3bc13dc0>
__del__
初始化__
__德尔__
但是,PyPy7.3.1(Python3.6.9)上的输出是

初始化__

未调用
\uu del\uu
函数。

tldr答案是否定的。据我所知,Pypy没有实现引用计数。为了证明这一点,我制作了一个简单的程序:

类测试:
定义初始化(自):
打印(“初始化”)
定义(自我):
打印(“删除”)
t=测试()
打印(t)
CPython 3.8.2的输出为:

__init__
<__main__.Test object at 0x7f6e3bc13dc0>
__del__
初始化__
__德尔__
但是,PyPy7.3.1(Python3.6.9)上的输出是

初始化__

\uu del\uu
函数未被调用。

即使在CPython上,答案也是。如果对象附加到长期缓存实例,则永远不会调用
\uu del\uu
。更好的设计模式是为对象使用上下文管理器,并在
\uuuuuuuuuuuuuu退出时进行清理:

with make_a_connection(parameter) as conn:
    useconn(conn)

即使在CPython上,答案也是否定的。如果对象附加到长期缓存实例,则永远不会调用
\uu del\uu
。更好的设计模式是为对象使用上下文管理器,并在
\uuuuuuuuuuuuuu退出时进行清理:

with make_a_connection(parameter) as conn:
    useconn(conn)

请阅读更详细的答案。感谢@ArminRigo提供参考。类似C++的析构函数将是伟大的,但尝试最后也工作。阅读也为更详细的答案。谢谢@ ARMIGRIO的参考。类似C++的析构函数将是伟大的,但是尝试最终也是有效的。对象被保证是短的生存的,对象被保证是短暂的。