0

在 Python 中,实现单例模式的一种方法是使用元类。

class Singleton(type):
    def __init__(cls, name, bases, dict):
        super(Singleton, cls).__init__(name, bases, dict)
        cls.INSTANCE = None

    def __call__(cls, *args, **kwargs):
        if cls.INSTANCE is None:
            cls.INSTANCE = super(Singleton, cls).__call__(*args, **kwargs)
        return cls.INSTANCE

但是在带有 PyDev dict 参数的 Eclipse 中会引发警告:Assignment to reserved built-in symbol: dict.

PEP 8 还说:

如果函数参数的名称与保留关键字发生冲突,通常最好在结尾附加一个下划线,而不是使用缩写或拼写错误。因此 class_ 比 cls 好。(也许更好的是通过使用同义词来避免这种冲突。)

我在网上发现分配给参数而不是dict的不同名称,例如dictionary、classdict和attrs。

以及使用 *args 和 **kwargs 的方法:

class Singleton(type):
    def __init__(cls, *args, **kwargs):
        super(Singleton, cls).__init__(*args, **kwargs)
        cls.INSTANCE = None

    def __call__(cls, *args, **kwargs):
        if cls.INSTANCE is None:
            cls.INSTANCE = super(Singleton, cls).__call__(*args, **kwargs)
        return cls.INSTANCE

我认为最后一个片段是最好的,因为如果类型 init 方法更改了他的签名,它是安全的。

问题:

  1. 您为参数分配什么名称而不是 dict?

  2. 您如何看待最后一个片段?

  3. 你认为最好的选择是什么?更改参数名称或使用 *args 和 **kwargs?

4

1 回答 1

0
  1. dict是一个内置类型,你可以使用namespaceorattributes或者其他什么来代替。在这里并不重要,它只是一个局部变量名。

    不需要将其命名为任何特定的名称,因为它是一个位置参数。数据模型文档使用namespace.

  2. 在那里使用*argsand**kwargs非常好。事实上,__init__()元类的 可以传递额外的关键字参数,因此将这些参数传递给超级__init__方法是一种很好的做法。

  3. 当我不关心参数时,我会使用*args和。**kwargs这样,您就可以在未来证明该方法。

请注意,在 Python 3 中,您不再需要提供super()任何参数:

class Singleton(type):
    def __init__(cls, *args, **kwargs):
        super().__init__(*args, **kwargs)
        cls.INSTANCE = None

    def __call__(cls, *args, **kwargs):
        if cls.INSTANCE is None:
            cls.INSTANCE = super().__call__(*args, **kwargs)
        return cls.INSTANCE
于 2013-03-25T17:41:14.117 回答