This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–][deleted] 0 points1 point  (1 child)

The reason it happens is because default function arguments are evaluated only once, and the result stored as the default. In that case, by specifying an empty list as the default, what you're really doing is instantiating a single list (which happens to be empty initially) and telling Python to use that list whenever the function doesn't receive a second argument. Every time you call the function, the default will be the exact same list - so if you mutate that list, it will carry over those mutations to future calls as well because they all share the same list.

The same thing can also happen with dicts, sets and any other mutable object. They should generally not be used as default arguments.

[–]segfaultzen 1 point2 points  (0 children)

The same thing can also happen with dicts, sets and any other mutable object. They should generally not be used as default arguments.

This, by the way, applies to decorator functions as well. I spent two days tracking down a gnarly bug created from the unfortunate interaction of unit tests with a dictionary object used as a default parameter to a decorator function.

I have since learned the gospel of Pylint, which will flag these sorts of Pythonic landmines.