Dangerous Python Default Arguments

Dangerous? Really? Well, not if you understand how it works.

Note: I’m not the first to write about this subject.

When writing a function in Python, it’s handy to use default argument values like this:

And you think this will provide an easy way to let lazy callers pass no arguments to your function, and it will simply be called as if they had passed ['some item'].

But you would be wrong.

What actually happens is this (interactive shell output):

That’s right. Python creates a new object, named some_list that persists as an attribute of the function. If callers don’t pass their own some_list object, this one, the same one, is used each time your function is called.

Weird, huh?

If users pass their own some_list object, then sanity is restored:

So why is this? Python stores each default argument value in a special attribute on the function called func_defaults. You can inspect any function’s default arguments like this:

Because functions in Python are just objects, you can store arbitrary attributes on them. And indeed, you can actually modify the default function arguments at run time, like this:

But remember: Just because you can doesn’t mean you should. I would not recommend making a habit of stuff like this, especially if you like not having your co-workers hate you.

It’s always good to know how your tools work. Inside and out.

I discovered this behavior when investigating the pylint W0102 message, and discovered that this message actually inspired an entire wiki of Pylint message descriptions.

Write a Reply or Comment

Your email address will not be published.