Page David
Page David

Reputation: 1413

how default arguments work in python

I have just read an article: The 10 Most Common Mistakes That Python Developers Make. The problem #1 still puzzled me a lot. I will describe my problem with the codes below.

>>>def foo(bar=[]):
...    bar.append("baz")
...    return bar
>>> foo()
["baz"]
>>> foo()
["baz", "baz"]

It not works, the answer in the article says list is an multable type and the default value changes during the call.But when I try this one

def foo(bar=[]):
    if bar == []:bar=[]
...

it works, so what makes the difference?

Upvotes: 1

Views: 123

Answers (2)

niemmi
niemmi

Reputation: 17263

In your code you assign a new list to bar instead using the default argument. Now if you modify the new list the changes of course aren't shown in the default argument which is different object.

The typical solution is to assign None to the default argument and explicitly check it at the beginning of function:

def foo(bar=None):
    if bar is None:
        bar = []

Note that although it looks a lot like your version there are differences:

def foo(bar=[]):
    if bar == []:
        bar = []
    bar.append(1)

def foo2(bar=None):
    if bar is None:
        bar = []
    bar.append(1)

l = []
foo(l)
print l # []

l = []
foo2(l)
print l # [1]

Upvotes: 0

pzp
pzp

Reputation: 6597

Default arguments are created at function definition in Python. This means that when you provide a list as a default argument, that list will persist for all function calls in which that argument is not explicitly passed. In the second example, you are reassigning the argument to a different value. That creates a new list and will fix the problem. A more common solution to this "bug"/"feature" is to assign the default argument a value of None and then check it at the top of the function. That would look something like this:

def foo(bar=None):
    if bar is None:
        bar = []

However, the code that you wrote in the second example achieves the same effect.

Upvotes: 4

Related Questions