Reputation: 3454
I came across Peter Norvig's implement of singleton class here http://norvig.com/python-iaq.html
def singleton(object, instantiated=[]):
"Raise an exception if an object of this class has been instantiated before."
assert object.__class__ not in instantiated, \
"%s is a Singleton class but is already instantiated" % object.__class__
instantiated.append(object.__class__)
class YourClass:
"A singleton class to do something ..."
def __init__(self, args):
singleton(self)
...
My problem is, if we create two YourClass instances, in the second time, why instantiated
is not a empty list? What's the scope of instantiated
?
Thank you.
Upvotes: 4
Views: 40
Reputation: 52173
From docs:
Important warning: The default value is evaluated only once. This makes a difference when the default is a mutable object such as a list, dictionary, or instances of most classes. It accumulates the arguments passed to it on subsequent calls.
The value of instantiated
is bound to function definition and is initialized only once when you define singleton
.
Because of this, every time you call the function, you'll have only one copy of same list:
def test(x, instantiated=[]):
instantiated.append(x)
print instantiated
>>> test(3)
[3]
>>> test(5)
[3, 5]
>>> test(6)
[3, 5, 6]
It is same as:
>>> lst = []
>>> def test(x, instantiated):
... instantiated.append(x)
... print instantiated
>>> test(3, lst)
[3]
>>> test(5, lst)
[3, 5]
>>> test(6, lst)
[3, 5, 6]
If you want instantiated
to be isolated between subsequent function calls, you should define it as a local variable
:
def test(x, instantiated=None):
if instantiated is None:
instantiated = []
instantiated.append(x)
print instantiated
>>> test(3)
[3]
>>> test(5)
[5]
>>> test(6)
[6]
Upvotes: 1