0

I am defining a singleton class, and using that class as a metaclass to create new classes.

class Singleton(type):
    _lock: Lock = Lock()
    _instance = {}

    def __call__(cls, *args, **kwargs):
        with cls._lock:
            if cls not in cls._instance:
                _instance = super().__call__(*args, **kwargs)
                cls._instance[cls] = cls

        return cls._instance.get(cls)

and the new class is defined like below

class SomeClass(metaclass=Singleton):
    def __init__(self, some_list = []):
         self.some_list = some_list

    def add_to_list(self, a):
         self.some_list.append(a)


some_class = SomeClass()

I am not able to access some_list variable of some_class object. It throws invalid attribute error.

some_class.some_list

a_list = [1,2,4,5]
for l in a_list:
    some_class.add_to_list(l)

Also, I am not able to call add_to_list fn. It throws missing paramter "a" in the arguments.

Can some one help what I am missing in understanding of metaclass concept.

1 Answer 1

0

Your error is here:

      cls._instance[cls] = cls

It should be:

      cls._instance[cls] = _instance

You are storing the class itself on your class registry, not its single instance.

Before we proceed, I will point another problem your code:

    def __init__(self, some_list = []):

Don't ever put a mutable object (an empty list) as a default parameter for a function or method: every time that function is called, the same object is re-used. In this case, this would be mitigated due to the method being in a singleton class, so this __init__ should run only once, but this is wrong enough. The correct pattern is:

    def __init__(self, some_list = None):
         if some_list is None:
              some_list = []

This ensures a new, different, list is created each time the method is executed.

And, another thing, I don't know why this recipe of metaclass to create a singleton got so popular, but it is definitely overkill - I talk about it in some other answers, including Create singleton class in python by taking advantage of meta class , Dill doesn't seem to respect metaclass and Accessing the parameters of a constructor from a metaclass .

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.