在Python中,实现Singleton模式的方法是使用元类。
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
但是在Eclipse中使用PyDev dict参数会发出警告:Assignment to reserved built-in symbol: dict
。
PEP 8也说:
如果函数参数的名称与保留关键字冲突,则为 通常更好地附加单个尾随下划线而不是 使用缩写或拼写损坏。因此class_比 CLSS。 (或许最好是通过使用同义词来避免这种冲突。)
我在网上发现了分配给参数而不是dict的不同名称,例如字典,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方法改变了他的签名是安全的。
问题:
您为参数而不是dict分配了什么名称?
您如何看待这最后一段代码?
您认为最佳选择是什么?更改参数名称或使用* args和** kwargs?
答案 0 :(得分:0)
dict
是一种内置类型,您可以使用namespace
或attributes
或其他类型。这里并不重要,它只是一个局部变量名。
不需要将它命名为任何特定的,因为它是位置参数。 datamodel documentation使用namespace
。
使用*args
和**kwargs
非常好。实际上,元类的__init__()
可以传递其他关键字参数,因此最好将这些参数传递给超级__init__
方法。
当我不关心参数时,我会使用*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