【问题标题】:implement singleton with metaclass用元类实现单例
【发布时间】:2011-10-17 05:45:56
【问题描述】:

下面的代码是我如何使用元类实现单例,并且效果很好

class Test_MetaClass(type):

    def __init__(cls, name, bases, dict):
        super(Test_MetaClass, cls).__init__(cls, bases, dict)
        cls._instance = None
        print 'Test_MetaClass __init__'

    def __call__(cls, *args, **kwargs):
        if cls._instance is None:
            cls._instance = super(Test_MetaClass, cls).__call__(*args, **kwargs)
        print 'Test_MetaClass __call__'
        return cls._instance


class A(object):
    __metaclass__ = Test_MetaClass
    def __init__(self):
        print 'A __init__ triggered'

a = A()
b = A()

输出:

Test_MetaClass __init__
A __init__ triggered
Test_MetaClass __call__
Test_MetaClass __call__

我的问题是为什么b = A() 直接转到Test_MetaClass.__call__ 而忽略__init__

【问题讨论】:

  • 您的元类可以更简单。不是答案,因此您必须处理评论格式。 class Singleton(type): cls._instance = None; def __call__(cls, *args, **kwargs): if cls._instance is None: cls._instance = super(Singleton, cls).__call__(*args, **kwargs); return cls._instance;

标签: python python-2.x metaclass


【解决方案1】:

这不是你想要的吗? cls._instance 不是 None,所以它不会执行 type.__call__(cls, *args, **kwargs):

>>> type.__call__(A)
A __init__ triggered
<__main__.A object at 0x00BADB30>

通过这个调用,A.__new__A.__init__ 被调用来创建/初始化一个新实例。但是对于您的单身人士,您只需要一个实例。

【讨论】:

  • 是的,没错,我没注意到__init__ 是通过__call__ 触发的
猜你喜欢
  • 1970-01-01
  • 2016-01-26
  • 2017-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多