Possible Duplicate:
“Least Astonishment” in Python: The Mutable Default Argument
Consider the following two functions
def a(var=[0]):
print (var)
var = var + [4]
def b(var=[0]):
print (var)
var.append(4)
They should act the same, but more importantly, both should simply print '[0]' if called with no arguments. The act very differently and only a() will print '[0]' all the time.
>>> a()
[0]
>>> a()
[0]
>>> a()
[0]
>>> b()
[0]
>>> b()
[0, 4]
>>> b()
[0, 4, 4]
Why does a() function differently from b()?
It seems like you can't use the list API if you want the variable to be overwritten with the default in the case that no arguments are past to the function. And if you do the function will 'remember' what it the variable was previously.
The situation in my code appears in a recursive function, so just 'del'-ing the unwanted variable won't really work. Is there a way to overwrite a variable every time you call the function with no arguments?
After hours and hours of research I discovered this. It might be related to the question above and might lead to an answer. We can define a lifetime class like so:
class lifetime: # adapted from http://naml.us/blog/tag/variable-lifetime
def __init__(self, name):
self.name = name
print ('creating: ' + name)
def __del__(self):
print ('destroying: ' + self.name)
def __iadd__(self, a):
self.append(a)
def append(self, a):
self.name += ' and ' + a.name
print('appending: ' + a.name + ' to ' + self.name)
and then define 2 functions:
def a(var=lifetime('a')):
print (var)
var += life('appendage')
def b(var=lifetime('b')):
print (var)
var.append(life('appendage'))
>>> a()
<__main__.lifetime object at 0x00000000031FFA90>
creating: appendage
appending: appendage to a and appendage
destroying: appendage
>>> a()
<__main__.lifetime object at 0x00000000031FFA90>
creating: appendage
appending: appendage to a and appendage and appendage
destroying: appendage
>>> b()
<__main__.lifetime object at 0x00000000031FFB38>
creating: appendage
appending: appendage to b and appendage
destroying: appendage
>>> b()
<__main__.lifetime object at 0x00000000031FFB38>
creating: appendage
appending: appendage to b and appendage and appendage
destroying: appendage
It seems like it just evaluates the default for the argument once, and then uses whatever the evaluation for that was. It never says, 'creating: a' or 'creating: b'. So maybe if it were to evaluate the default argument each time, it would lead to an answer to the actual question.