我有一个包装类,我将其子类化为我们使用的许多数据库连接。我想要一些与try/finally
功能类似的东西,但仍然给我一个类的灵活性和子类化潜力。这是我的基类,我想替换__del__
方法,因为我已经读过某个地方,无法保证何时运行。
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()
答案 0 :(得分:1)
根据相关问题的最佳答案:What is the __del__ method, How to call it?
当您的对象被垃圾收集时,将调用height
方法,但正如您所指出的那样,无法保证在销毁对象的引用之后多久会发生这种情况。
在您的情况下,由于您在尝试关闭连接之前检查是否存在连接,因此可以安全地多次调用max-height
方法,因此您可以在销毁引用之前简单地调用它。你的对象。