【问题标题】:Singleton across modules跨模块单例
【发布时间】:2012-06-11 17:21:17
【问题描述】:

我正在尝试实现单例,但在导入模块时遇到了困难。我的设置如下。我正在使用 Python 2.7。

模块 1

class SingletonClass(object):
    def __new__(self, *args, **kwargs):
        if not self._instance:
            self._instance = super(SingletonClass, self).__new__(
                                self, *args, **kwargs)
        return self._instance

print SingletonClass()  #OUTPUT: 0x00000000030F1630
print SingletonClass()  #OUTPUT: 0x00000000030F1630 (Good, what I want)

模块 2

import SingletonClass

class AnotherClass:
    print SingletonClass.SingletonClass() #OUTPUT: 0x0000000003292208

在模块中,单例正在工作,但在另一个模块中,单例返回的对象与第一个模块中的对象不同。知道为什么吗?

编辑

现在,我将放置我发现的唯一有效的东西。我确信有更好的解决方案,但我认为这可能更好地传达潜在问题是什么。

模块 1

class SingletonParent(object):
    _instance = None

    def __new__(self, *args, **kwargs):
        if not self._instance:
            self._instance = super(SingletonParent, self).__new__(
                                self, *args, **kwargs)
        return self._instance

模块 2

import SingletonParent    
class SingletonClass(object):
        def __new__(self, *args, **kwargs):
            if not SingletonParent.SingletonParent._instance:
               SingletonParent.SingletonParent._instance = super(SingletonClass, self).__new__(
                            self, *args, **kwargs)
            return SingletonParent.SingletonParent._instance 

    print SingletonClass()  #OUTPUT: 0x00000000030F1630
    print SingletonClass()  #OUTPUT: 0x00000000030F1630

模块 3

import SingletonClass

class AnotherClass:
    print SingletonClass.SingletonClass() #OUTPUT: 0x00000000030F1630

解决方案(编辑 3)

教训:不要把你的 main 函数和你的 Singleton 放在同一个模块中!

【问题讨论】:

  • Python singleton pattern 的可能重复项
  • 你所拥有的不可能工作,我的意思是你会在第二个模块中的importSingletonClass() 收到错误。另外,为什么print 声明在类定义中?这段代码没有任何意义。
  • @kindall 这是伪代码。这大致是我所拥有的,但我试图简化一些事情以提高可读性。
  • 那么……您发布的代码有效:<a.SingletonClass object at 0x10bef8e10> <a.SingletonClass object at 0x10bef8e10> <a.SingletonClass object at 0x10bef8e10> — 您能发布一些代码来证明您的问题吗?
  • @DavidWolever 我认为问题在于我组织模块的方式。我现在拥有它的方式每个模块都有自己的对象版本。我不确定为什么你会得到不同的结果。我应该指出我使用的是 Python 2.7。此外,当我创建一个名为 SingletonParent 的新模块和类并让 SingletonClass 成为它的唯一导入器时,一切正常。如果可能的话,我宁愿避免这种实现。

标签: python design-patterns singleton


【解决方案1】:

您的问题很可能是模块以两个不同的名称被导入两次。

要对此进行测试,请添加以下内容:

print "Being imported..."

module1.py

如果此消息被打印两次,则模块被导入两次,这就是您的问题。要修复它,请确保您使用相同的名称在任何地方导入模块[0],并且您没有使用 sys.path 进行黑客攻击。

[0]:从技术上讲,这不应该是必要的,但这是一个简单的修复。

【讨论】:

  • 它确实打印了两次,但我不确定我的问题出在哪里。在 Mod1 中,我导入 Mod2 和 Mod3。在 Mod2 和 Mod 3 中,我导入 Mod1。这是不好的做法吗?
  • 那是你的问题。您可以使用import traceback, sys; traceback.print_exception(*sys.exc_info()) 找出它是从哪里导入的,这将打印回溯。
  • 如果你有一个循环导入(mod1 importing mod3, mod3 importing mod1),那么一定有一些你没有提到的东西,因为那应该是不可能(除非其中一个模块只从内部函数导入另一个,或者以其他方式推迟导入)。
  • 我认为这是我问题的核心。我来自一个常见的 Java/C++ 世界。 Mod1 的 A 类是一个单例,它使用我在 Mod2 中的 B 类。 B 类必须使用单例的一些功能。在这种情况下,Mod1 必须导入 Mod2,而 Mod1 必须导入 Mod1。我这样做是为了便于阅读。两者都是大类,如果将它们分开会更容易。
  • 不过,这并没有真正解决我的陈述——那么,你肯定没有提到某些东西,因为循环导入是不可能
猜你喜欢
  • 2012-10-31
  • 1970-01-01
  • 1970-01-01
  • 2023-01-04
  • 2012-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多