使DB连接跨多个python模块可用的正确方法
我想在许多python模块中提供一个数据库对象 对于一个相关示例,我创建了globl.py:使DB连接跨多个python模块可用的正确方法,python,mysql,Python,Mysql,我想在许多python模块中提供一个数据库对象 对于一个相关示例,我创建了globl.py: DOCS_ROOT="c:\docs" ## as an example SOLR_BASE="http://localhost:8636/solr/" 任何其他需要它的模块都可以执行以下操作: from globl import DOCS_ROOT 现在撇开这个例子不谈,我想对数据库连接对象做同样的事情,在多个模块中共享它们 import MySQLdb conn = MySQLdb.connec
DOCS_ROOT="c:\docs" ## as an example
SOLR_BASE="http://localhost:8636/solr/"
任何其他需要它的模块都可以执行以下操作:
from globl import DOCS_ROOT
现在撇开这个例子不谈,我想对数据库连接对象做同样的事情,在多个模块中共享它们
import MySQLdb
conn = MySQLdb.connect (host="localhost"...)
cursor = conn.cursor()
我在口译员身上试过:
from globl import cursor
这似乎奏效了。但我怀疑这将导致每次从中导入时执行相同的模块。那么这是正确的方法吗?你猜错了。代码只执行一次-后续导入仅通过
sys.modules
引用模块,不重新运行
(请注意,只要始终使用相同的路径导入模块,就会出现这种情况-如果在一个位置从全局导入光标执行,在另一个位置从my.fullyqualified.project.global导入光标执行,您可能会发现代码被重新执行。)
编辑以添加正如S.Lott在评论中所说,这是处理全局对象的一种非常好的方法。我认为Daniel已经回答了这个问题,而我想添加一些关于您想要共享的游标对象的评论
这样共享游标对象通常不是一个好主意。当然,这取决于您的程序是什么,但作为一种通用解决方案,我建议您将此游标对象隐藏在“工厂”生成的游标后面。基本上,您可以创建一个方法cursor()
或get\u cursor()
,而不是将光标设为全局变量。主要的好处(但不是唯一的)
您可以在这个“工厂”后面隐藏一个更复杂的逻辑--池、连接断开时自动重新连接等。即使您不需要立即使用它,如果您现在开始使用此方法,以后也很容易添加它,而现在,您可以让这个函数实现像return\u cursor
一样简单
当然,模块本身只会导入一次 即使导入没有多次运行代码,这肯定不是正确的方法 您应该将获取连接或光标的过程隐藏在函数后面。然后可以使用或设计模式实现此功能 所以应该是这样的: db.py:
_connection = None
def get_connection():
global _connection
if not _connection:
_connection = MySQLdb.connect(host="localhost"...)
return _connection
# List of stuff accessible to importers of this module. Just in case
__all__ = [ 'getConnection' ]
## Edit: actually you can still refer to db._connection
## if you know that's the name of the variable.
## It's just left out from enumeration if you inspect the module
import db
conn = db.get_connection() # This will always return the same object
someothermodule.py:
_connection = None
def get_connection():
global _connection
if not _connection:
_connection = MySQLdb.connect(host="localhost"...)
return _connection
# List of stuff accessible to importers of this module. Just in case
__all__ = [ 'getConnection' ]
## Edit: actually you can still refer to db._connection
## if you know that's the name of the variable.
## It's just left out from enumeration if you inspect the module
import db
conn = db.get_connection() # This will always return the same object
顺便说一句,根据你正在做什么,分享可能不是一个好主意
连接对象,而不是每次需要时都创建一个新的连接对象
但是,这就是为什么您希望编写一个
get_connection()
方法,以便在代码的其余部分中从这些问题中抽象出来。关于“这是正确的方法吗?”我认为您应该指出,这样的全局模块从长远来看效果非常好。这也是一个很好的答案。如果我运行这段代码,我会得到UnboundLocalError:之前引用的局部变量“\u connection”assignment@Jim没错。这是一个仓促的例子。我添加了一行带有global\u connection
。使用\uuuu all\uuuu
还有一个很好的特性,即使用import*
表示将要导入命名空间的内容。并不是说如果你能帮上忙,你就应该使用import*
。:-)我以后会提到这一点。这是一种在简单界面后面制作复杂内容的好方法。