How to adapt the Singleton pattern? (Deprecation warning)

后端 未结 3 1116
佛祖请我去吃肉
佛祖请我去吃肉 2021-02-07 11:18

Few years ago I found an implementation of the Singleton pattern in Python by Duncan Booth:

class Singleton(object):
    \"\"\"
    Singleton class by Duncan Boo         


        
相关标签:
3条回答
  • 2021-02-07 11:40

    You need to drop any additional arguments you are passing when you construct the object. Change the offending line to:

            cls._instance = object.__new__(cls)
    

    or

            cls._instance = super(Singleton, cls).__new__(cls)
    

    though I think you'll be fine with the first (diamond inheritance and singletons sound as though they shouldn't be mixed).

    P.S. I did try this suggestion and it works for me so I don't know why it didn't work for you.

    Edit in response to @dragonx's comment: As pointed out in the comments, object.__new__ will throw an exception if you pass on *args, **kwargs so the super call to __new__ should not include any arguments apart from cls. This wasn't the case when the original article was written. Also of course if you choose to base your singleton on some other type such as a tuple you would then need to pass the appropriate arguments.

    0 讨论(0)
  • 2021-02-07 11:44

    I found this pattern described in a Python 3 pattern and idioms source. This should certainly help. I would love to know if it solves your problem, although it may violate the minimal impact condition in your question.

    Python 3: The Singleton

    0 讨论(0)
  • 2021-02-07 11:57

    So based on the answers from @Sven and @Duncan I found a solution which works for me. The problem actually wasn't in the line of the code raising the TypeError, but in the signature of the __new__() method. The call of the object.__new__(cls) shall be without the *args, **kwargs, but they have to remain in the Singleton.__new__() definition. This is the modified Singleton:

    class Singleton(object):
        """
        Singleton class by Duncan Booth.
        Multiple object variables refers to the same object.
        http://www.suttoncourtenay.org.uk/duncan/accu/pythonpatterns.html
        """
       _instance = None
    
        def __new__(cls, *args, **kwargs):
            if not cls._instance:
                cls._instance = super(Singleton, cls).__new__(cls)
            return cls._instance
    

    And this is an example of sub-classing (which was the issue):

    class Child(Singleton):  
        def __init__(self,param=None):  
                print param  
                print 'Doing another stuff'  
    
    ch=Child('Some stuff')
    

    I still don't understand why the signature of Child's __init__() has to match to Singleton's `new(), but this solution works.

    0 讨论(0)
提交回复
热议问题