Why Is the Empty Dictionary a Dangerous Default Value in Python

Why is the empty dictionary a dangerous default value in Python?

It's dangerous only if your function will modify the argument. If you modify a default argument, it will persist until the next call, so your "empty" dict will start to contain values on calls other than the first one.

Yes, using None is both safe and conventional in such cases.

Best practice for setting the default value of a parameter that's supposed to be a list in Python?

Use None as a default value:

def func(items=None):
if items is None:
items = []
print items

The problem with a mutable default argument is that it will be shared between all invocations of the function -- see the "important warning" in the relevant section of the Python tutorial.

Mutable Default Arguments - (Why) is my code dangerous?

Assuming that doInsert() (and whatever code doInsert is calling) is only ever reading collection, there is indeed no immediate issue - just a time bomb.

As soon as any part of the code seeing this list starts mutating it, your code will break in the most unexpected way, and you may have a hard time debugging the issue (imagine if what changes is a 3rd part library function tens of stack frames away... and that's in the best case, where the issue and it's root cause are still in the same direct branch of the call stack - it might stored as an instance attribute somewhere and mutated by some unrelated call, and then you're in for some fun).

Now the odds that this ever happens are rather low, but given the potential for subtles (it might just result in incorrect results once in a while, not necessarily crash the program) and hard to track bugs this introduces, you should think twice before assuming that this is really "safe".

default argument in function for creating a dictionary creates an infinete loop of self references

Using empty dictionary as defaults are actually bad ideas, mainly because dictionaries are mutable objects, meaning if you accidentally changing the content of the dictionary, it is there to stay (cause reference to object stays the same). See: Why is the empty dictionary a dangerous default value in Python?

I would suggest changing your populateTree function to something like:

def populateTree(self, tag, text='', attr=None, children=None):
if attr is None:
attr = {}
if children is None:
children = {}
return {'tag': tag, 'text': text, 'attr': attr, 'children': children}

so it creates a new empty dictionary everything populateTree is called without those arguments.

mypy gives Incompatible default for argument when Dict param defaults None

I think the type should be "dict or None", so a Union of the two:

def example(self, mydict: Union[Dict[int, str], None] = None):
return mydict.get(1)

What is the pythonic way to avoid default parameters that are empty lists?

def my_func(working_list=None):
if working_list is None:
working_list = []

# alternative:
# working_list = [] if working_list is None else working_list

working_list.append("a")
print(working_list)

The docs say you should use None as the default and explicitly test for it in the body of the function.

Least Astonishment and the Mutable Default Argument

Actually, this is not a design flaw, and it is not because of internals or performance. It comes simply from the fact that functions in Python are first-class objects, and not only a piece of code.

As soon as you think of it this way, then it completely makes sense: a function is an object being evaluated on its definition; default parameters are kind of "member data" and therefore their state may change from one call to the other - exactly as in any other object.

In any case, the effbot (Fredrik Lundh) has a very nice explanation of the reasons for this behavior in Default Parameter Values in Python.
I found it very clear, and I really suggest reading it for a better knowledge of how function objects work.



Related Topics



Leave a reply



Submit