【问题标题】:Good practice sharing resources between modules? [closed]在模块之间共享资源的良好做法? [关闭]
【发布时间】:2012-11-18 12:32:23
【问题描述】:

我正在重新组织我的代码并因此创建新的命名空间。我正在为模块更改“静态”类(每个方法中带有 @staticmethod 的类)。这是要走的路,对吧?

问题是我对如何在这些模块之间共享资源有疑问。

假设我有一个模块,我通过该模块与数据库进行所有连接,当然所有类/方法都共享存储 DB 游标的变量(我使用的是 SQLite)。现在,在不同的模块中,它们也必须共享光标。

所以,我的想法:

  • 在每个模块中声明全局变量。但是全球人是邪恶的,吃掉孩子,偷走我们的工作。所以我不知道这是否是要走的路。

    '''Sub Module 1'''
    
    global database_cursor
    
  • 使用原始的 database_cursor 导入“父亲”database_module 并使用如下内容:

    '''Sub Module 1'''
    
    db_cursor = database_module.database_cursor
    

在这种情况下,这一秒看起来不错,但我认为在许多情况下会导致递归导入,我想这是应该避免的。

【问题讨论】:

  • 我想你可能是overengineering。如果函数需要光标来处理,只需将参数cursor 添加到函数中即可。调用所有函数的代码将创建一个包含光标的局部变量并将其传递给所有函数。另外,我想说一个用于数据库管理的模块就足够了。如果你发现你需要更多的组织,那么你最好使用 SQLAlchemy 之类的东西。
  • 我不认为这是过度工程。共享数据库连接之类的东西以避免不必要的重新初始化是完全合法的。但是,我确实认为为此考虑连接池是明智的。否则,您可能会遇到上一次通话仍在使用的连接问题。

标签: python module namespaces globals


【解决方案1】:

你的第二种方法是要走的路。 Python 导入本质上是单例的。当一个模块被多次导入时,它只会在第一次执行。随后的导入从全局中获取模块对象实例。更多关于 here.

shared.py:

class Shared:
    def __init__(self):
        print("Init shared")

    def do_stuff(self, from_mod):
        print("Do stuff from {0}. I am instance {1}".format(from_mod, self))

shared = Shared()

foo.py

import shared

shared.shared.do_stuff("foo")

bar.py

import foo
import shared

shared.shared.do_stuff("bar")

如果我们执行 bar.py,我们会得到:

>>> Init shared
>>> Do stuff from foo. I am instance <shared.Shared instance at 0x10046df38>
>>> Do stuff from bar. I am instance <shared.Shared instance at 0x10046df38>

因此,在您的情况下,您可以从任何您想要的地方引用database_module,并且它只会被初始化一次,因此可以有效地共享您的连接。

【讨论】:

  • 如果依次分别执行 foo.py 和 bar.py 是否意味着 init 方法执行了两次?我试图了解当同一个模块在一个模块内或跨模块导入多个时,单例行为是否适用?
  • 请注意,在 python 文档docs.python.org/3/reference/… 中,这个过程没有写得太明确;关键语句是“必要时初始化”,其中“必要时”被解释为“之前没有初始化过”。
猜你喜欢
  • 2021-09-24
  • 2017-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-07
相关资源
最近更新 更多