11th
Static Initializers for Optional Arguments
I had an issue with Python recently. It turns out that optional arguments are initialized statically. What does that mean? Well, it means that having an optional argument initialized to the empty list for later manipulation is a bad idea. For example:
class Foo:
def __init__(self, dependencies = []):
self.dependencies = dependencies
if __name__ == "__main__":
f1 = Foo()
f2 = Foo()
f1.dependencies.append(f2)
print f2.dependencies[0] is f2
When run, the code prints True. The reason is that the dependencies in the optional argument list is initialized statically. So each call to Foo() uses the same empty list. So, when I added f2 to f1’s dependencies, it was implicitly added to f2’s dependencies as well, because they were the same dependencies.
This lead to a not-so-subtle bug in the code I was working on, as nearly everything had the same dependencies. If you want such an optional argument, but with the intended semantics, try this:
class Foo:
def __init__(self, dependencies = None):
if dependencies is None:
self.dependencies = []
else:
self.dependencies = dependencies
Or some variation on that.