dimanche 5 avril 2020

Why is my method that returns a Singleton class returning different instances of the object?

I am trying to do the following:

  • Create a class with an inner, private class
  • The inner class is a Singleton, but takes a parameter into the constructor where a new parameter means that a new instance is created
  • Create a method in the outer class which returns an instance of the inner class, maintaining my definition of a Singleton with parameter above.

Here is a sample of the code:

class Outer:

    def __init__(self):
        pass

    def new(self, name):
        return self._Inner(name)

    class _Inner(metaclass=Singleton):

        def __init__(self, name):
            pass

import inspect    

    class Singleton(type):
    """ 
    Singleton that keep single instance for single set of arguments. 
    E.g.:
        assert Singleton('spam') is not Singleton('eggs')
        assert Singleton('spam') is Singleton('spam')
    """
    _instances = {}
    _init = {}

    def __init__(cls, name, bases, dct):
        cls._init[cls] = dct.get('__init__', None)

    def __call__(cls, *args, **kwargs):
        init = cls._init[cls]
        if init is not None:
            key = (cls, frozenset(
                inspect.getcallargs(init, None, *args, **kwargs).items()))
        else:
            key = cls

        if key not in cls._instances:
            cls._instances[key] = super(
                Singleton, cls).__call__(*args, **kwargs)
        return cls._instances[key]

When I run this code:

outer = Outer()

a = outer._Inner('a')
b = outer._Inner('b')
a2 = outer._Inner('a')

print(a == b)
print(a2 == a)

a = outer.new('a')
b = outer.new('b')
a2 = outer.new('a')

print(a == b)
print(a2 == a)

I get this output

False
True
False
False

Why doesn't calling the method that returns the Singleton object act the same as calling the Singleton objects directly, and how can I achieve this?

Aucun commentaire:

Enregistrer un commentaire