Python novice often make mistakes (the first part) reprint

Think of this article for the python default parameters of good writing, translation is also good, the reproduced under.


The original link:  Amir Rachum

Translation:   -  Bole Bole online   online readers

The link:  


Translation is as follows:

Before a few months, I teach some don't know Python children to become familiar with the language. Gradually, I found some almost all Python beginners may make mistakes, so I decided to share my advice with you. This series of each part will focus on common errors, describes how to produce this kind of errors, and provide solutions.

With a variable's value as a default value

This is a definitely worth in the first place, problems. Just because the BUG is very subtle, and this problem is also very difficult to check out. Thinking about the following code fragment:

1

2

3

l !important;">def foo(numbersl !important;">=[]):

numbers.append(l !important;">9)

print numbers

Here, we define a list (the default is empty), add to it the 9 and print it out.

1

2

3

4

5

6

>>> foo()

[l !important;">9]

>>> foo(numbersl !important;">=[l !important;">1,l !important;">2])

[l !important;">1, l !important;">2, l !important;">9]

>>> foo(numbersl !important;">=[l !important;">1,l !important;">2,l !important;">3])

[l !important;">1, l !important;">2, l !important;">3, l !important;">9]

Look OK? But when we did not come to call the foo function input for the number parameter, amazing thing happened.:

1

2

3

4

5

6

7

8

>>> foo() # first time, like before

[l !important;">9]

>>> foo() # second time

[l !important;">9, l !important;">9]

>>> foo() # third time...

[l !important;">9, l !important;">9, l !important;">9]

>>> foo() # WHAT IS THIS BLACK MAGIC?!

[l !important;">9, l !important;">9, l !important;">9, l !important;">9]

So, this is what the situation? Intuition tells us whether we do not enter the number parameter to invoke the foo function many times, the 9 should be divided into an empty list. This is wrong! In Python, the default value is function when the function definition instantiated, rather than at the time of the call.

Then we will ask, why when calling the function of the default values have been given different values? Because every time you to specify a default value, Python will store the value. If the override function call when the default value, then the stored value will not be used. When you do not override the default value, then Python will let the default reference the stored value (in this case numbers). It is not stored value is copied to the variable assignment. This concept can be for beginners, understanding would be more difficult, so it can be to understand: there are two variables, one is inside, one is the current run-time variables. The reality is that we have two variables with the same values are interactive, so once the numbers value changes, will change Python which stores the initial value of the record.

Then the solutions are as follows:

1

2

3

4

5

l !important;">def foo(numbersl !important;">=None):

l !important;">if numbers l !important;">is None:

numbers l !important;">= []

numbers.append(l !important;">9)

print numbers

Usually, when the people heard this, they will ask another question about the default value. Consider the following program:

1

2

3

l !important;">def foo(countl !important;">=l !important;">0):

count l !important;">+l !important;">= l !important;">1

print count

When we run it, the result is we expect:

1

2

3

4

5

6

7

8

9

10

>>> foo()

l !important;">1

>>> foo()

l !important;">1

>>> foo(l !important;">2)

l !important;">3

>>> foo(l !important;">3)

l !important;">4

>>> foo()

l !important;">1

This is why? The secret is not to default values assigned time, but this default value itself. Integer is an immutable variables. Unlike the list type, in the course of function, integer variables can not be changed. When we perform count+=1 this sentence, we have not changed the original value of the variable count. But let count points to a different value. But, when we perform numbers.append (9) time, we changed the original list. Thus caused the results.

Here is another the same problems encountered using the default value in the function.:

1

2

l !important;">def print_now(nowl !important;">=time.time()):

print now

As before, the time.time () is the value of the variable, then it will only be calculated when the function definition, so no matter how many times the call, will return to the same event — the output events are interpreted by Python program running time.

1

2

3

4

5

6

>>> print_now()

l !important;">1373121487.91

>>> print_now()

l !important;">1373121487.91

>>> print_now()

l !important;">1373121487.91

* The problem and its solution are similar in Python 2.x and 3.x Python 3.x, in which the only difference, is inside the print expression should be a function call.(print(numbers)).

* We should note that I use the if  in the solution; numbers is None not if not numbers. This is another common mistake, I'm ready to introduce in this article.

Posted by Ailsa at November 25, 2013 - 6:34 PM