While I was watching some code about singleton’s in python I decided to write my own.
This was my first code:
def singleton(cls):
instance = False
def constructor(*args,**kwargs):
if not instance:
instance = cls(*args,**kwargs)
return instance
return constructor
But when i tested it, the interpreter told me that ‘instance’ must be declared before being used on the if condition, finally I figured out to do it as follows:
def singleton(cls):
cls._instance = False
def constructor(*args,**kwargs):
if not cls._instance:
cls._instance = cls(*args,**kwargs)
return cls._instance
return constructor
and it worked as expected:
>>> @singleton
>>> class A: pass
>>> a=A()
>>> id(a)
33479456
>>> b=A()
>>> id(b)
33479456
Why the closure from the first example didn’t work.
Edit: the error was
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "singleton.py", line 4, in constructor
if not instance:
UnboundLocalError: local variable 'instance' referenced before assignment
Your first closure didn’t work because inside your
constructorfunction, you assigned toinstance. That makesinstancea local name insideconstructor, and you accessed that local name before it was assigned to.In Python 3, you can use
nonlocal instanceto declare the scope ofinstance. In Python 2, you can’t access that outerinstancename as you want to.Also, singletons are unusual in Python. Why not just instantiate your class once? Why try to trick Python into behaving differently than it does? Or create a factory function to produce the instance to use?