Skip to content

Commit 50a880f

Browse files
guillermo-carrascoJoelQ
authored andcommitted
Added trick about mutable arguments
The default argument refers to the same object over multiple invocations of a function, leading to some surprising mutation bugs.
1 parent b5ef717 commit 50a880f

File tree

1 file changed

+52
-0
lines changed

1 file changed

+52
-0
lines changed

python/mutable_default_arguments.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Mutable default arguments
2+
3+
__NOTE__: Information taken from [python guide](http://docs.python-guide.org/en/latest/writing/gotchas/)
4+
5+
One of the most confusing moments for new developers is when they discover how
6+
Python treats default arguments in function definitions.
7+
8+
Let's say you want to define a function that accepts a list as a parameter, and you
9+
want the default value of that list to be the empty list, so you write:
10+
11+
```python
12+
def append_to(element, to=[]):
13+
to.append(element)
14+
return to
15+
```
16+
17+
If everything was okay, you would expect the following behavior:
18+
19+
```
20+
my_list = append_to(12)
21+
print my_list
22+
23+
my_other_list = append_to(42)
24+
print my_other_list
25+
```
26+
27+
```
28+
[12]
29+
[42]
30+
```
31+
32+
But what you get instead is:
33+
34+
```
35+
[12]
36+
[12, 42]
37+
```
38+
39+
A new list is created once when the function is defined, and the same list is used in each successive call.
40+
41+
Python’s default arguments are evaluated once when the function is defined, instead of each time the function is called (like it is in say Ruby). This means that if you use a mutable default argument and mutate it, you will and have mutated that object for all future calls to the function as well.
42+
43+
### What you should do
44+
Create a new object each time the function is called, by using a default arg to signal that no argument was provided (`None` is often a good choice):
45+
46+
```python
47+
def append_to(element, to=None):
48+
if to is None:
49+
to = []
50+
to.append(element)
51+
return to
52+
```

0 commit comments

Comments
 (0)