Python 保证数据库连接在类中使用后关闭?
我有一个包装器类,它是我们使用的许多数据库连接的子类。我希望它的行为类似于Python 保证数据库连接在类中使用后关闭?,python,python-3.x,Python,Python 3.x,我有一个包装器类,它是我们使用的许多数据库连接的子类。我希望它的行为类似于try/finally功能,但仍能给我类的灵活性和子类化潜力。这是我的基类,我想替换\uu del\uu方法,因为我在某个地方读到,无法保证它何时运行 class DatabaseConnBase: def __init__(self, conn_func, conn_info: MutableMapping): self._conn = None self.conn_func =
try/finally
功能,但仍能给我类的灵活性和子类化潜力。这是我的基类,我想替换\uu del\uu
方法,因为我在某个地方读到,无法保证它何时运行
class DatabaseConnBase:
def __init__(self, conn_func, conn_info: MutableMapping):
self._conn = None
self.conn_func = conn_func
self.conn_info = conn_info
def _initialize_connection(self):
self._conn = self.conn_func(**self.conn_info)
@property
def conn(self):
if not self._conn:
self._initialize_connection()
return self._conn
@property
def cursor(self):
if not self._conn:
self._initialize_connection()
return self._conn.cursor()
def __del__(self):
if self._conn:
self._conn.close()
def commit(self):
if not self._conn:
raise AttributeError(
'The connection has not been initialized, unable to commit '
'transaction.'
)
self._conn.commit()
def execute(
self,
query_or_stmt: str,
verbose: bool = True,
has_res: bool = False,
auto_commit: bool = False
) -> Optional[Tuple[Any]]:
"""
Creates a new cursor object, and executes the query/statement. If
`has_res` is `True`, then it returns the list of tuple results.
:param query_or_stmt: The query or statement to run.
:param verbose: If `True`, prints out the statement or query to STDOUT.
:param has_res: Whether or not results should be returned.
:param auto_commit: Immediately commits the changes to the database
after the execute is performed.
:return: If `has_res` is `True`, then a list of tuples.
"""
cur = self.cursor
if verbose:
logger.info(f'Using {cur}')
logger.info(f'Executing:\n{query_or_stmt}')
cur.execute(query_or_stmt)
if auto_commit:
logger.info('Committing transaction...')
self.commit()
if has_res:
logger.info('Returning results...')
return cur.fetchall()
根据这一相关问题的首要答案: 垃圾收集对象时,将调用
\uuu del\uu
方法,但正如您所指出的,无法保证销毁对对象的引用后多久会发生这种情况
在您的情况下,由于您在尝试关闭连接之前检查连接是否存在,因此可以安全地多次调用
\uu del\uu
方法,因此您可以在销毁对对象的引用之前显式调用它。使用上下文管理器显式执行此操作。您的类将需要\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。