Python子模块如何共享稀缺资源?

4 投票
2 回答
1626 浏览
提问于 2025-04-16 21:47

我正在把一个很大的Python文件拆分成六个小模块。

最开始在一个叫做onebigfile.py的文件里,我有:

conn = MySqldb.connect()
c = conn.cursor()

然后一个函数会这样使用它:

def getFromDB():
     c.execute(sql)

现在,我已经重新整理了我的模块,变成了:

NewModule/
  __init__.py
  users.py
  accounts.py
  sixmoreofthese.py

我现在在想,像我的MySQL连接这种比较稀缺的资源该怎么处理。

有没有办法访问父命名空间,比如说可以把conn.c.放在__init__.py里?我不想创建很多MySQL连接。直接把它们放在那里,然后像全局变量那样调用是行不通的……也就是说:

__init__.py:
   conn = MySqldb.connect()
   c = conn.cursor() 

> import NewModule
> NewModule.users.login('a','b')
--- login function calls the Mysql c. from the global namespace and can't find it. 

为了预见一个建议:拆分这些文件是有道理的——大约有5万到7万行的Python代码,还有一群人需要一起使用这些代码,并且功能上有比较明确的分组。

2 个回答

2

我现在在想的是,像我的 MySQL 连接这种资源比较稀缺的东西该怎么处理。

我不太确定我这样做是否特别符合 Python 的风格,但我通常会把“需要被多个模块使用的东西”放在一个单独的模块里,然后在每个需要用到它的模块中单独导入。

补充一下:我使用类方法是为了在需要的时候只自动初始化一次某个东西。

8

你可以在 Python 模块之间共享连接对象,你的想法是把连接设置为模块范围内的变量,这样做是很好的(除了少数例外,Python 模块是单例的,所以即使从不同的文件多次导入,它们也只会加载一次)。不过,你可能不想在模块之间共享同一个游标对象,特别是在多线程环境下使用时(比如在 mod_wsgi 或类似的环境中运行网页应用)。

一个建议是把连接放到一个特定于数据库的模块里,比如 db.py,然后通过一个 get_connection() 方法来初始化和访问它。这样可以让你的应用程序优雅地加载连接所需的任何配置(用户名、密码、主机名)。这可能简单得多,像这样:

# db.py
connection = None
def get_connection():
    global connection
    if not connection:
        connection = MySqldb.connect() # possibly with configuration vars passed in
    return connection

你其他使用数据库的代码可以像这样:

# other_module.py
import db
curs = db.get_connection().cursor()
# do stuff
curs.close()

撰写回答