可能重复:
在Python中定义单例是否有简单,优雅的方法?
我有以下示例代码,其中我从Singleton派生一个类(希望它是一个):
class Singleton(object):
_instance = None
def __new__(cls, *args, **kwargs):
if not cls._instance:
cls._instance = object.__new__(cls, *args, **kwargs)
return cls._instance
class Tracer(Singleton):
def __init__(self):
print "Init"
a = Tracer()
b = Tracer()
Run Code Online (Sandbox Code Playgroud)
当你尝试它时,你会看到再次调用__init__方法Tracer.是不是有单身人士让另一个实例引用原始实例?我不想__init__再次运行该方法,因为它可能会覆盖以前的信息.也许单身人士是错的还是有用的?
class A(SomeBaseClass):
def __init__(self):
super().__init__()
self._attribute_0 = something_0
self._attribute_1 = something_1
# etc.
def some_method(self) -> None:
do_something()
Run Code Online (Sandbox Code Playgroud)
现在假设您有类似的类B, C, D, etc.(并非所有类都继承自同一基类)。它们都具有一些各自的功能,并且从逻辑的角度来看,它们很好地封装在这些类中。关键的一点是,对于这些类中的每一个,一次总是只有一个实例存在。问题是,有时一个类需要访问另一个类的函数,即
if __name__ == "__main__":
a = A()
b = B(a)
c = C()
d = D(c, a)
b.d = d
etc.
Run Code Online (Sandbox Code Playgroud)
假设存在多个 class 实例,这段代码对我来说是合理的A, B, etc.,但由于一次总是只有一个实例存在,因此总是在构造函数中传递它们似乎有点多余(实际上,这些类当然有更复杂的名称)并且“main”函数变得非常难以阅读......)。
尽管存在争议,但在其他语言中,一种解决方案是辛格尔顿模式。似乎有一些方法可以在Python中实现单例(参见这里),但它们似乎不被鼓励(即有些人甚至说Python中永远不需要它们)。
我的目标相当简单:我希望我的对象a,b,c, etc.可以在整个项目中访问,而不必在构造函数中传递它们或通过 等来一一设置它们b.d = d。
这在Python中可能吗?我有什么选择?
@blue_note 的回答插图
# objects.py
a = A()
b = B(a)
c = …Run Code Online (Sandbox Code Playgroud) 目前我正在使用一个相当简单的单例实现.但是,我从来没有在网上看到过这样的建议,这让我觉得它可能有问题......
class Singleton:
def __init__():
raise ...
@staticmethod
def some():
pass
@staticmethod
def another():
pass
Run Code Online (Sandbox Code Playgroud)
单例的这种实现是否有任何缺点(使所有类成员都是静态的).它有点类似于使用模块作为单例,除了你把所有东西都包装在一个类中.
编辑:我知道在Python中实现单例的其他方法.我不喜欢它们的是它们都不是显式的(这违背了Python zen):
因为我做的a = Class()不是类似的事情a = Class.Instance(),所以我在处理具有共享状态的对象时并不明显(参见注释#1).如果所有成员都是静态的,我至少有Class.someMethod()哪种类型表明它是单身.我不喜欢这种方法的是你不能使用构造函数和析构函数,它消除了单例对自由函数的主要优势,这是你在创建和销毁它们时可以做的事情(参见注释#2) .
注意#1:我知道我不应该关心单身人士的状态(如果我这样做,那么它首先不应该是单身人士).我仍然希望明确它是什么类.
注意#2:创建单例时,可以在其构造函数中进行一些实例化.例如,在处理图形库的单例中,您可以在constrctor中初始化库.这种方式实例化和解除实例在sinleton的构造函数和析构函数中自动发生.
或者在ResourceManager中:析构函数可以检查在销毁时是否仍然存在内存中的资源并相应地执行操作.
如果你使用自由函数而不是单例,你必须手动完成所有这些.
我的代码是:
class Handler():
# make it static
from pymongo import MongoClient
client = MongoClient("localhost", 27017)
db = client.newsdb
news = db.news
Run Code Online (Sandbox Code Playgroud)
我想让 client 变量成为静态变量,那么上面的代码是正确的方法吗?我也想使用单例模式,因为也许 MongoClient 是非常大的元素,当我真正需要它时我想 new() 这个元素......
我怎样才能在 python 中做到这一点?作为一个初学者,可能会问一些愚蠢的问题,提前抱歉......
我有一个抽象类,我想为从我的抽象类继承的所有类实现Singleton模式.我知道我的代码不起作用,因为会有元类属性冲突.任何想法如何解决这个问题?
from abc import ABCMeta, abstractmethod, abstractproperty
class Singleton(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
return cls._instances[cls]
class GenericLogger(object):
__metaclass__ = ABCMeta
@abstractproperty
def SearchLink(self): pass
class Logger(GenericLogger):
__metaclass__ = Singleton
@property
def SearchLink(self): return ''
a = Logger()
Run Code Online (Sandbox Code Playgroud) 我已经阅读了许多解释如何在python中实现单例的文章,比如 在Python中创建单例
我很想知道,不是一个带类方法的类,属性是一个单例类.
例如
class my_singleton_class(object):
_logger = Logger ()
_printer = Printer ()
@classmethod
def logger(cls):
return cls._logger
@classmethod
def printer(cls):
return cls._printer
Run Code Online (Sandbox Code Playgroud)
它不是pythonic吗?这个单例实现有什么问题?
使用此问题中的方法 1 实现了单例:
def singleton(class_):
instances = {}
def getinstance(*args, **kwargs):
if class_ not in instances:
instances[class_] = class_(*args, **kwargs)
return instances[class_]
return getinstance
@singleton
class MyClass(BaseClass):
pass
Run Code Online (Sandbox Code Playgroud)
当我在本地运行它时,它在本地工作,但是当我使用gunicorn和django-crontabs部署它时,它看起来好像单例无法维持并且该类的多个实例被实例化。我想知道每个 Gunicorn 工作人员是否都会生成该类的一个单独实例。简而言之,我询问的是使用 Gunicorn 运行 Web 应用程序时与 Python 和 Django 的交互。
我是Python的新手,我想通过检查并创建Python设计模式示例来学习这种语言。
我对Singleton Pattern的经典实现感到困惑。那里的大多数文章都提到将Singleton实现为经典
class Singleton(object):
name = None
@staticmethod
def instance():
if '_instance' not in Singleton.__dict__:
Singleton._instance = Singleton()
return Singleton._instance
s1 = Singleton().instance();
s2 = Singleton().instance();
assert s1 is s2
Run Code Online (Sandbox Code Playgroud)
但是我对此实现并不完全相信,因为在任何地方我们都不能限制用户创建Singleton类的多个对象,并且我仍然可以通过调用Singleton()来创建此类的实例。在Java中,我们通过将类的构造函数设置为Private来防止这种情况。
有人指出我的另一个实现是
class Singleton(object):
_instances = {}
def __new__(class, *args, **kwargs):
if class not in class._instances:
instance = super().__new__(class)
class.__instances[class] = instance
return class._instances[class]
Run Code Online (Sandbox Code Playgroud)
这使我头昏了头脑。有人可以解释一下这是怎么回事吗
我已经使用 MetaClass 创建了一个单例,如本答案的方法 3 中所述
class Singleton(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
return cls._instances[cls]
class MySing(metaclass=Singleton): ...
Run Code Online (Sandbox Code Playgroud)
我希望能够在 a 的setUp()方法中清除单例,unittest.TestCase以便每个测试都以干净的单例开始。
我想我真的不明白这个元类在做什么,因为我无法获得一个clear()方法的正确咒语:
def clear(self):
try:
del(Singleton._instances[type(self)]
except KeyError:
pass #Sometimes we clear before creating
Run Code Online (Sandbox Code Playgroud)
对我在这里做错了什么有任何想法吗?我的单身人士没有被清除。
sing=MySing()
sing.clear()
Run Code Online (Sandbox Code Playgroud)
type上面的调用返回Singletonnot MySing。