How can I use keyword args in an initialiser without sharing it between instances of a class?
Example of the bad behaviour below, if I were to add anything to the set foo
then it would be added in both instances.
In [1]: class Klass:
def __init__(self, foo=set()):
self.foo = foo
In [2]: a = Klass()
In [3]: b = Klass()
In [4]: a.foo is b.foo
Out[4]: True
Note that this issue will only occur with mutable default arguments - see "Least Astonishment" and the Mutable Default Argument. To use a mutable default argument, it is conventional to set the default to None
in the function definition, then check inside the function whether or not a value has been supplied:
class Klass:
def __init__(self, foo=None):
if foo is None:
foo = set()
self.foo = foo
or:
self.foo = foo if foo is not None else set()
Note that None
is tested by identity (if foo is None:
), not equality (if foo == None:
) or truthiness (if not foo:
). For example, the latter is an issue if you want to explicitly pass in an empty set you have referenced elsewere.