Search code examples
pythonpython-3.xinstancestatic-variables

Can I create a singleton static class variable in python?


I have the following scenario:

class A:
   b = 1
   pass

x = A()
y = A()

Can I change this class so that x.b = 2 is equivalent to A.b = 2, I mean, when a change the static variable for one instance it´s changed for all instances?

Edit: I want to be able to work with multiple different instances of this class.


Solution

  • You can, but it's kind of ugly:

    class A:
        b = 1
        def __setattr__(self, name, value):
            if name == "b":
                setattr(A, "b", value)
            else:
                super().__setattr__(name, value)
    

    This would work as expected now:

    >>> a = A()
    >>> a.b = 3
    >>> A.b
    3
    >>> A.b = 5
    >>> a.b
    5
    

    The real question is: Why would you want that?


    If you're going to use this often, it might be nice to write a decorator for it:

    def sharedclassvar(variable):
        def __setattr__(self, name, value):
            if name in self.__class__._sharedclassvars:
                setattr(self.__class__, name, value)
            elif hasattr(self.__class__, "__oldsetattr__"):
                self.__class__.__oldsetattr__(self, name, value)
            else:
                super().__setattr__(name, value)
        def decorator(cls):
            if not hasattr(cls, "_sharedclassvars"):
                cls._sharedclassvars = []
                if hasattr(cls, "__setattr__"):
                    cls.__oldsetattr__ = getattr(cls, "__setattr__")
                    cls.__setattr__ = __setattr__
            cls._sharedclassvars.append(variable)
            return cls
        return decorator
    

    You can then define such a class like this:

    @sharedclassvar("b")
    class A:
        b = 1