DEV Community

Cover image for Python Mutable Defaults Are The Source of All Evil

Python Mutable Defaults Are The Source of All Evil

Florimond Manca on August 14, 2018

Today, I wanted to share a quick life-saving advice about a common mistake Python developers still tend to make. TL;DR Do not use mutab...
Collapse
 
mrgnth profile image
Thomas Schmitt

Would you consider

seq = seq or []

a viable alternative to your if-construction?

Collapse
 
florimondmanca profile image
Florimond Manca • Edited

Yes, I would see that as a viable alternative :-) — although I would argue that:

  • I see the if X is None check in Python code more often — not sure it means anything in terms of "pythonicism", though!
  • This only works when the default is simple enough to build. If it needs multiple lines to be built, we'll have to resort to if X is None anyway.
Collapse
 
moylop260 profile image
Moises Lopez - https://www.vauxoo.com/ • Edited

We have a static check to avoid these kind of issues

def my_method(vals=[]):
    pass
Enter fullscreen mode Exit fullscreen mode

pylint -d all -e dangerous-default-value edi_expense.py

The output will be: (dangerous-default-value) Dangerous default value [] as argument

You can use pylint in your CI in order detect them early

Collapse
 
thehesiod profile image
Alexander Mohr

Another option is using a non mutable type like a tuple

Collapse
 
florimondmanca profile image
Florimond Manca • Edited

Yep, that would solve it if your argument can be transformed to use a non-mutable version.
However, Python is already so confusing on types that I wouldn’t recommend providing a tuple if you’re to use a list afterwards.
I like to use type annotations, so annotating an argument as a List while providing an empty tool for the default would look suspicious. ;)

Collapse
 
qaisjp profile image
Qais Patankar

What do you think about

def append(element, seq??=None):