Inappropriately marked as a duplicate question. This has nothing to do with not knowing how to pass a variable by reference. It is asking if there is a way to mitigate the issues with keeping a mutable optional argument as a parameter without its value persisting in the function's context on subsequent calls.
So I just had this happen to me today and am now familiar with this trap that many new Python developers fall into: mutable default arguments. For brevity, here's an example of what I'm taking about:
def MyClass(object):
...
def my_func(self,my_str="default",my_dict={},**kwargs):
my_dict.update(kwargs)
self.my_dict = my_dict
----------------------------------------
<< a = MyClass()
<< a.my_func(foo='bar')
<< a.my_dict
>> {'foo':'bar'}
<< b = MyClass()
<< b.my_func(bar='baz')
<< b.my_dict
>> {'foo': 'bar', 'bar': 'baz'}
I understand that this is intentional and understand that a good solution would be to modify my_func
to this instead:
def my_func(self,my_str="default",my_dict=None,**kwargs)
if my_dict is None: my_dict = {}
...
However I'm not satisfied with this. It just rubs me the wrong way. I don't want it to be None by default. I want an empty dict by default. So I thought of doing this:
def my_func(self,my_str="default", my_dict={}, **kwargs)
my_dict.update(kwargs)
self.my_dict = my_dict
my_dict = {}
But of course this won't work, you'll get the same behavior as before. But why? Isn't my_dict
persistent and mutable? Or only when convenient for Python? Is there any other way to deal with this aside from simply excluding my_dict
as an optional arg?
I'm really hung up on this because I find it useful to use a default argument to convey a type to the reader, which boosts code readability IMO. It's good because the reader wouldn't need to dive into the function to determine that my_dict
is supposed to be a dict (inb4 suggesting "just use comments" - idealistic, but not very realistic for my purposes).
This "feature" makes little sense and is so incredibly offensive to me that I'm actually very close to believing that it's really a bug in disguise. No one will ever use this and it's almost a dealbreaker for me.
Thanks in advance.