Python 2.7 Python 2.7.6:如何正确清理类?
在下面的可执行代码中,您会看到一个Python 2.7 Python 2.7.6:如何正确清理类?,python-2.7,class,Python 2.7,Class,在下面的可执行代码中,您会看到一个SessionScope()-类。在main()-函数中,用户可以登录到MySQL数据库服务器。我们在课堂上看一看。有两种神奇的方法(\uuuuuu enter\uuuuu,\uuuuu exit\uuuu), 这使我可以通过with-语句轻松地使用对象。在此语句中,您还可以看到程序使用会话。当\uuuu退出
SessionScope
()-类。在main
()-函数中,用户可以登录到MySQL数据库服务器。我们在课堂上看一看。有两种神奇的方法(\uuuuuu enter\uuuuu,\uuuuu exit\uuuu)
,
这使我可以通过with
-语句轻松地使用对象。在此语句中,您还可以看到程序使用会话。当\uuuu退出
()-方法为
调用,然后会话关闭。但我们知道这会将连接返回到引擎的连接池。也就是说,它不会直接关闭连接,
因为连接是池连接。到现在为止,一直都还不错。在GUI端,用户可以选择注销。好吧,让我们想象一下:在与
数据库用户希望实际关闭连接,但不希望程序自行关闭。稍后,用户可能会再次登录并继续工作。在此之前,程序仍在运行,未连接到
数据库。用户不再需要连接
这意味着对于python,我们不再需要SessionScope
()-类。在我的例子中,我们可以使用del session\u scope
删除/清理这个类,我的想法是重新实现\u del\u
()-方法。用这种方法我想
关闭连接池的所有连接。如果清除/删除此类,则应断开所有连接,这就是我在log_out
()-功能中使用del
的原因
这样做对吗
塔,你的索菲斯
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.exc import SQLAlchemyError
class SessionScope(object):
def __init__(self, dbms, dbdriver, dbuser, dbuser_pwd, db_server_host, dbport, db_name):
self.dbms = dbms
self.dbdriver = dbdriver
self.dbuser = dbuser
self.dbuser_pwd = dbuser_pwd
self.db_server_host = db_server_host
self.dbport = dbport
self.db_name = db_name
url = '{}+{}://{}:{}@{}:{}/{}'.format(
self.dbms, self.dbdriver, self.dbuser, self.dbuser_pwd, self.db_server_host, self.dbport, self.db_name)
self.engine = create_engine(url, encoding='utf8', echo=True)
# store a sessionmaker for this db connection object
self._Session = sessionmaker(bind=self.engine)
self.session = None
def __enter__(self):
self.session = self._Session()
return self._Session()
def __exit__(self, exception, exc_value, traceback):
try:
if exception:
self.session.rollback()
else:
self.session.commit()
finally:
self.session.close()
self.session = None
def __del__(self):
self.engine.dispose()
def log_out(session_scope):
del session_scope
def main():
dbm_system = raw_input("Which DBMS? (type for e.g. mysql): ")
dbm_driver = raw_input("Which db-driver? (type for e.g. pymysql): ")
db_host = raw_input("Server-Host: ")
db_user = raw_input("Database-user: ")
db_passwd = raw_input("User-Password: ")
db_name = raw_input("Database Name: ")
db_port = raw_input("Port: ")
try:
session_scope = SessionScope(dbm_system, dbm_driver, db_user, \
db_passwd, db_host, db_port, db_name)
with session_scope as session:
# Its just for testing.
print session.execute("SELECT VERSION();")
log_out(session_scope)
except SQLAlchemyError as err:
print "ERROR", err[0]
if __name__ == '__main__':
main()
编辑#1:
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.exc import SQLAlchemyError
class SessionScope(object):
def __init__(self, engine):
self.engine = engine
# store a sessionmaker for this db connection object
self._Session = sessionmaker(bind=self.engine)
self.session = None
def __enter__(self):
self.session = self._Session()
return self._Session()
def __exit__(self, exception, exc_value, traceback):
try:
if exception:
self.session.rollback()
else:
self.session.commit()
finally:
self.session.close()
self.session = None
class Engine(object):
def __init__(self, dbms, dbdriver, dbuser, dbuser_pwd, db_server_host, dbport, db_name):
self.dbms = dbms
self.dbdriver = dbdriver
self.dbuser = dbuser
self.dbuser_pwd = dbuser_pwd
self.db_server_host = db_server_host
self.dbport = dbport
self.db_name = db_name
url = '{}+{}://{}:{}@{}:{}/{}'.format(
self.dbms, self.dbdriver, self.dbuser, self.dbuser_pwd, self.db_server_host, self.dbport, self.db_name)
self._Engine = create_engine(url, encoding='utf8', echo=True)
def __enter__(self):
return self._Engine
def __exit__(self, exception, exc_value, traceback):
'''
Make sure the dbconnection gets closed
'''
self._Engine.dispose()
logged_in = True
def main():
dbm_system = raw_input("Which DBMS? (type for e.g. mysql): ")
dbm_driver = raw_input("Which db-driver? (type for e.g. pymysql): ")
db_host = raw_input("Server-Host: ")
db_user = raw_input("Database-user: ")
db_passwd = raw_input("User-Password: ")
db_name = raw_input("Database Name: ")
db_port = raw_input("Port: ")
try:
with Engine(dbm_system, dbm_driver, db_user, \
db_passwd, db_host, db_port, db_name) as engine:
while logged_in:
with SessionScope(engine) as session:
# Its just for testing.
print session.execute("SELECT VERSION();")
except SQLAlchemyError as err:
print "ERROR", err[0]
if __name__ == '__main__':
main()
\uuu del\uu
方法不是这样工作的。当用户删除某个实例时,不会调用它,而是当解释器的垃圾收集器看到没有对该对象的实时引用时,才会调用它。您的log\u out
方法不做任何操作,因为它正在删除的引用是一个额外的引用,创建该引用是为了将会话作为参数传递给它(外部引用仍然保留)
我怀疑您真的希望有两个不同的类,它们都支持上下文管理器协议。这使您有两个嵌套的with
语句,其中一个语句持续整个登录,每个数据库会话只持续一次。大概是这样的:
with Engine() as engine:
while logged_in:
with Session(engine) as session:
do_stuff()
您可能需要使用在外部
上进行另一个循环,以便程序在您注销后不会退出。\u del\u
方法不是这样工作的。当用户删除某个实例时,不会调用它,而是当解释器的垃圾收集器看到没有对该对象的实时引用时,才会调用它。您的log\u out
方法不做任何操作,因为它正在删除的引用是一个额外的引用,创建该引用是为了将会话作为参数传递给它(外部引用仍然保留)
我怀疑您真的希望有两个不同的类,它们都支持上下文管理器协议。这使您有两个嵌套的with
语句,其中一个语句持续整个登录,每个数据库会话只持续一次。大概是这样的:
with Engine() as engine:
while logged_in:
with Session(engine) as session:
do_stuff()
您可能需要使用
在外部上进行另一个循环,以便程序在您注销后不会退出。Blckknght:首先,TA需要您的帮助。我编辑了我的代码的新版本(编辑#1)。这就是你的意思吗?在这个新版本中,程序一直执行,直到logged\u In
为False。实际上是不可行的,因为用户进行了操纵。事实上,我认为while循环已经足够了,对吗?Blckknght:首先,感谢你的帮助。我编辑了我的代码的新版本(编辑#1)。这就是你的意思吗?在这个新版本中,程序一直执行,直到logged\u In
为False。实际上是不可行的,因为用户进行了操纵。实际上,我认为while循环就足够了,对吗?