在Python中似乎有很多方法来定义单例对象。对Stack Overflow是否有一致的意见?
当前回答
好吧,我知道,单胞胎可能是好的,也可能是坏的。这是我的实现,我只是扩展了一个经典的方法,在里面引入一个缓存,并产生许多不同类型的实例,或者许多相同类型的实例,但具有不同的参数。
我称它为Singleton_group,因为它将相似的实例分组在一起,并防止创建具有相同参数的相同类的对象:
# Peppelinux's cached singleton
class Singleton_group(object):
__instances_args_dict = {}
def __new__(cls, *args, **kwargs):
if not cls.__instances_args_dict.get((cls.__name__, args, str(kwargs))):
cls.__instances_args_dict[(cls.__name__, args, str(kwargs))] = super(Singleton_group, cls).__new__(cls, *args, **kwargs)
return cls.__instances_args_dict.get((cls.__name__, args, str(kwargs)))
# It's a dummy real world use example:
class test(Singleton_group):
def __init__(self, salute):
self.salute = salute
a = test('bye')
b = test('hi')
c = test('bye')
d = test('hi')
e = test('goodbye')
f = test('goodbye')
id(a)
3070148780L
id(b)
3070148908L
id(c)
3070148780L
b == d
True
b._Singleton_group__instances_args_dict
{('test', ('bye',), '{}'): <__main__.test object at 0xb6fec0ac>,
('test', ('goodbye',), '{}'): <__main__.test object at 0xb6fec32c>,
('test', ('hi',), '{}'): <__main__.test object at 0xb6fec12c>}
每个对象都携带单例缓存…这可能是邪恶的,但对一些人来说很有用:)
其他回答
如果你想继续装饰(注释)类,创建一个单例装饰器(又名注释)是一种优雅的方式。然后将@singleton放在类定义之前。
def singleton(cls):
instances = {}
def getinstance():
if cls not in instances:
instances[cls] = cls()
return instances[cls]
return getinstance
@singleton
class MyClass:
...
谷歌Testing博客上也有一些有趣的文章,讨论了为什么单例是/可能是不好的,并且是一种反模式:
单身人士是病态的说谎者 单身人士都去哪儿了? 单身的根本原因
由ActiveState提供的Python实现的单例模式。
看起来窍门是把应该只有一个实例的类放在另一个类中。
模块方法工作得很好。如果我绝对需要一个单例,我更喜欢元类方法。
class Singleton(type):
def __init__(cls, name, bases, dict):
super(Singleton, cls).__init__(name, bases, dict)
cls.instance = None
def __call__(cls,*args,**kw):
if cls.instance is None:
cls.instance = super(Singleton, cls).__call__(*args, **kw)
return cls.instance
class MyClass(object):
__metaclass__ = Singleton
在Python中实现单例的一个稍微不同的方法是Alex Martelli(谷歌员工和Python天才)的borg模式。
class Borg:
__shared_state = {}
def __init__(self):
self.__dict__ = self.__shared_state
因此,它们共享状态,而不是强制所有实例具有相同的标识。
推荐文章
- Django:“projects”vs“apps”
- 如何列出导入的模块?
- 转换Python程序到C/ c++代码?
- 如何从gmtime()的时间+日期输出中获得自epoch以来的秒数?
- 在python模块文档字符串中放入什么?
- 我如何在Django中过滤一个DateTimeField的日期?
- 在Python中用索引迭代列表
- -e,——editable选项在pip install中什么时候有用?
- 使用pip命令从requirements.txt升级python包
- Django更改默认的runserver端口
- 输入对象的datetime。Datetime没有Datetime属性
- numpy数组的Python内存使用情况
- NumPy或Pandas:保持数组类型为整数,同时具有NaN值
- 列表理解条件中的' elif '
- Python的“property”和“attribute”有什么区别?