Python中的全局变量和单例对象

2024-04-28 04:01:09 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一些在Python应用程序中广泛使用的类,它们应该只有一个全局实例(例如Logger、DbConnection)。Python不支持类中的静态变量/方法,所以通常使用java /C++方式创建一个单独的单元格是行不通的。我已经找到了在Python中实现singleton的替代方法。我想要一个简单(没有元编程,如果可能)和干净的实现。这看起来不错:

class MyClass(object):
    def a():
        pass

singleton = MyClass()

使用singleton很简单

^{pr2}$

如果对象初始化不是那么简单,直接赋值可以用创建函数代替。在

我还可以在模块范围内创建一个getInstance(),并始终使用它来获取myObj。在

问题1)这行得通吗?模块代码(myObj赋值)只在第一次导入其他模块时运行,而myObj不会在每次我将该模块导入某个地方时创建?在

我见过的另一种方法是使用globals模块。比如:

from myClass1 import MyClass1
from myClass2 import MyClass2

myObj1 = MyClass1()
myObj2 = MyClass2()

使用这个:

import globals
globals.myObj1.a()

我倾向于选择第一种。在

问题2)在这两种解决方案中,你有什么建议?在

问题3)第三种解决方案是将广泛使用的对象(如Logger)传递给多个类/函数,但这在imho中不是一个好的解决方案。有没有更好的解决方案没有提到这里?在

我知道使用全局变量和单变量的缺点。然而,在我的应用程序中,拥有全局状态并不是一个大问题。我更喜欢代码清晰且易于使用的解决方案。在


Tags: 模块对象方法函数代码import应用程序myclass
3条回答

正确的答案是如何使单身?不要。你应该显式地传递一个引用给所有需要使用它的对象。您可以使用工厂函数、包装类等来减少工作量。在

即使有一些东西,比如屏幕或记录器是全局性的,您仍然应该显式地传递它以允许单元测试。注意,这只适用于最终设计的一部分。如果您的日志只是一个快速的调试黑客,请随意使其全球化。在

考虑创建以下内容:

  1. 国家级的
  2. 代理类

state类将创建一个线程,该线程将在init.py模块中初始化。state类将具有将类实例传递到线程并将weakref保存到线程的方法。在

稍后,可以使用代理类访问线程中的类实例。如果没有创建类对象,那么代理将创建所需类的实例并将其保存到线程中。在

使用此模式,可以将每个类的实例数限制为1,并确保只要应用程序的某个部分正在运行,就不必重新创建需要全局重复使用的任何实例。在

如果您想要一个只有一个实例的logger类,只需将它作为一个单独的模块。在

# In logging.py
def log(msg):
  print msg

然后从任何你想登录的脚本。在

^{2}$

相关问题 更多 >