issue with singleton python call two times __init__

前端 未结 4 384
感情败类
感情败类 2020-12-10 07:30

I have a singleton like this

class Singleton:

    class __impl:
        def __init__(self):
            print \"INIT\"

    __instance = None

    def __ini         


        
4条回答
  •  借酒劲吻你
    2020-12-10 07:46

    Since we're all ignoring your question and instead proposing alternative singleton implementations, I'll pitch in with my favourite. It takes advantage of the fact that a python module is only loaded once, no matter how many times you import it.

    It's also based on the python motto "we're all consenting adults here" since, if you REALLY want to, you can instantiate it multiple times... but then you really have to put in an extra effort to do it wrong.

    So in mysingleton.py:

    class SingletonClass(object):
        def __init__(self):
            # There's absolutely nothing special about this class
            # Nothing to see here, move along
            pass
    
    # Defying PEP8 by capitalizing name
    # This is to point out that this instance is a Singleton
    Singleton = SingletonClass()
    
    # Make it a little bit harder to use this module the wrong way
    del SingletonClass
    

    Then use it like this:

    from mysingleton import Singleton
    
    # Use it!
    

    I said you had to put in an extra effort to do things wrong. Here's how you could create two instances of the singleton class, making it a singleton no more:

    another_instance = Singleton.__class__()
    

    So how do you avoid this problem? I'll quote the doctor: don't do that then!


    NOTE: This was added after the comments below were made

    While I'm at it, here's another singleton variant that minimizes the amount of complicated code. It uses metaclasses:

    class SingletonMeta(type):
        # All singleton methods go in the metaclass
        def a_method(cls):
            return cls.attribute
    
        # Special methods work too!
        def __contains__(cls, item):
            return item in cls.a_list
    
    class Singleton(object):
        __metaclass__ = SingletonMeta
        attribute = "All attributes are class attributes"
    
        # Just put initialization code directly into the class
        a_list = []
        for i in range(0, 100, 3):
            a_list.append(i)
    
    print Singleton.a_method()
    print 3 in Singleton
    

    In python 3 you'd create the singleton instance like this instead:

    class Singleton(metaclass=SingletonMeta):
        attribute = "One... two... five!"
    

    Now this one is a little more iffy, since the singleton is a class, and you can make instances of the singleton. In theory this is OK, since the singleton will still be a singleton even if it has instances, but you need to remember that Singleton() is not the singleton -- Singleton is! It might even suit your needs to have the singleton attributes readily available to its instances as class attributes.

提交回复
热议问题