Is there a simple, elegant way to define singleton

2018-12-31 04:36发布

This question already has an answer here:

There seem to be many ways to define singletons in Python. Is there a consensus opinion on Stack Overflow?

22条回答
伤终究还是伤i
2楼-- · 2018-12-31 05:08

The Singleton Pattern implemented with Python courtesy of ActiveState.

It looks like the trick is to put the class that's supposed to only have one instance inside of another class.

查看更多
梦醉为红颜
3楼-- · 2018-12-31 05:09

The Python documentation does cover this:

class Singleton(object):
    def __new__(cls, *args, **kwds):
        it = cls.__dict__.get("__it__")
        if it is not None:
            return it
        cls.__it__ = it = object.__new__(cls)
        it.init(*args, **kwds)
        return it
    def init(self, *args, **kwds):
        pass

I would probably rewrite it to look more like this:

class Singleton(object):
    """Use to create a singleton"""
    def __new__(cls, *args, **kwds):
        """
        >>> s = Singleton()
        >>> p = Singleton()
        >>> id(s) == id(p)
        True
        """
        self = "__self__"
        if not hasattr(cls, self):
            instance = object.__new__(cls)
            instance.init(*args, **kwds)
            setattr(cls, self, instance)
        return getattr(cls, self)

    def init(self, *args, **kwds):
        pass

It should be relatively clean to extend this:

class Bus(Singleton):
    def init(self, label=None, *args, **kwds):
        self.label = label
        self.channels = [Channel("system"), Channel("app")]
        ...
查看更多
何处买醉
4楼-- · 2018-12-31 05:10
class Singeltone(type):
    instances = dict()

    def __call__(cls, *args, **kwargs):
        if cls.__name__ not in Singeltone.instances:            
            Singeltone.instances[cls.__name__] = type.__call__(cls, *args, **kwargs)
        return Singeltone.instances[cls.__name__]


class Test(object):
    __metaclass__ = Singeltone


inst0 = Test()
inst1 = Test()
print(id(inst1) == id(inst0))
查看更多
残风、尘缘若梦
5楼-- · 2018-12-31 05:11

The one time I wrote a singleton in Python I used a class where all the member functions had the classmethod decorator.

class foo:
  x = 1

  @classmethod
  def increment(cls, y = 1):
    cls.x += y
查看更多
后来的你喜欢了谁
6楼-- · 2018-12-31 05:11

Being relatively new to Python I'm not sure what the most common idiom is, but the simplest thing I can think of is just using a module instead of a class. What would have been instance methods on your class become just functions in the module and any data just becomes variables in the module instead of members of the class. I suspect this is the pythonic approach to solving the type of problem that people use singletons for.

If you really want a singleton class, there's a reasonable implementation described on the first hit on Google for "Python singleton", specifically:

class Singleton:
    __single = None
    def __init__( self ):
        if Singleton.__single:
            raise Singleton.__single
        Singleton.__single = self

That seems to do the trick.

查看更多
君临天下
7楼-- · 2018-12-31 05:17

The module approach works well. If I absolutely need a singleton I prefer the Metaclass approach.

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
查看更多
登录 后发表回答