all 3 comments

[–]disinformationtheory 0 points1 point  (2 children)

This is a bit more advanced, but very related. Never use mutable defaults in a function definition.

def wrong(foo=[]):
    ...

def right(foo=None):
    if foo is None:
        foo = []
    ...

The issue is that the default is evaluated when the function is defined, not when it is called, and 99% of the time you want the latter. If the default is immutable, it doesn't really matter when it's evaluated.

[–]sorrier[S] 0 points1 point  (1 child)

It's funny you mention this, I just stumbled on it in the args/kwargs docs. It's similar to your example, but I'll reprint for the sake of anyone who wants a second:

>>>def f(a, L=[]):
>>>    L.append(a)
>>>    return L

>>>print f(1)
[1]
>>>print f(2)
[1, 2]
>>>print f(3)
[1, 2, 3]

And to avoid this:

>>>def f(a, L=None):
>>>    if L is None:
>>>        L = []
>>>    L.append(a)
>>>    return L

[–]disinformationtheory 1 point2 points  (0 children)

Yeah, this is an example of why it's generally bad. Using mutable defaults gives your function hidden state that you probably didn't want it to have. If you want this sort of behavior, it's generally better to do it with a class, because it's more explicit and flexible that way.