在许多python模块中提供数据库连接的正确方法

Jes*_*ose 9 python mysql

我想在许多python模块中创建一个单独的数据库对象.

对于相关示例,我创建了globl.py:

DOCS_ROOT="c:\docs" ## as an example
SOLR_BASE="http://localhost:8636/solr/"
Run Code Online (Sandbox Code Playgroud)

任何其他需要它的模块都可以做到

from globl import DOCS_ROOT
Run Code Online (Sandbox Code Playgroud)

现在抛开这个例子,我想对数据库连接对象同样的事情,在许多模块之间共享它们.

import MySQLdb
conn = MySQLdb.connect (host="localhost"...)
cursor = conn.cursor()
Run Code Online (Sandbox Code Playgroud)

我在翻译上尝试了这个:

from globl import cursor
Run Code Online (Sandbox Code Playgroud)

它似乎工作.但我怀疑这会导致每次模块导入时执行相同的模块.这是正确的方法吗?

Zec*_*ecc 33

即使导入没有多次运行代码,这绝对不是正确的方法.

您应该隐藏在函数后面获取连接或光标的过程.然后,您可以使用SingletonObject Pool设计模式实现此功能.

所以它会是这样的:

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
Run Code Online (Sandbox Code Playgroud)

someothermodule.py:

import db
conn = db.get_connection() # This will always return the same object
Run Code Online (Sandbox Code Playgroud)

顺便说一句,根据你在做什么,分享你的连接对象可能不是一个好主意,而不是每次需要时创建一个新的连接对象.

但是,这就是为什么你想编写一个get_connection()方法,从代码的其余部分中抽象出这些问题.


Dan*_*man 5

你怀疑错了。该代码只会执行一次 - 后续导入仅引用该模块 via sys.modules,并且不会重新运行它。

(请注意,只要您始终使用相同的路径来导入模块,就会出现这种情况 - 如果您from globl import cursor在一个地方这样做,而from my.fullyqualified.project.global import cursor在另一个地方这样做,您可能会发现代码被重新执行。)

编辑添加,正如 S.Lott 在评论中所说,这是处理全局对象的完美方法。