An in-depth discussion of the cause of the problem caused by the default value of the parameters of the Python function _python

Source: Internet
Author: User
Tags closure in python

This article describes the potential hazards of using the Mutable object as the default value of the Python function parameter, and its implementation principles and design objectives
Trap Recurrence

Let's use practical examples to illustrate the main things we're going to discuss today.

The following section of code defines a function called Generate_new_list_with. The purpose of this function is to create a new list containing the given element value each time it is called. The actual operating results are as follows:

Python 2.7.9 (default, Dec 2014, 06:05:48)
[GCC 4.2.1 compatible Apple LLVM 6.0 (clang-600.0.56)] on Darwin
TYP E "Help", "copyright", "credits" or "license" for the more information.
>>> def generate_new_list_with (my_list=[], element=none):
...   My_list.append (Element)
...   Return my_list ...
>>> list_1 = Generate_new_list_with (element=1)
>>> list_1
[1]
>>> list_2 = Generate_new_list_with (element=2)
>>> list_2
[1, 2]
>>>

The results of the visible code run are not the same as we expected. Instead of getting a new list and filling in 2 at the second invocation of the function, list_2 append a 2 on the basis of the first invocation of the result. Why does this happen in other programming languages just like bugs?
Preparation knowledge: The essence of Python variables

To understand the reason for this problem, we need a preparation knowledge first, that is: How is python variable actually implemented?

Python variables differ from the Declaration & assignment methods of other programming languages, using a pointer-like approach to creating & pointing. That is, the variables in Python are actually a pointer to a value or object (they are simply worth a name). Let's take a look at an example.

p = 1
p = p+1

For traditional languages, the above code will be executed by first declaring a P variable in memory and then storing 1 in the memory of the variable p. When performing the addition operation, the result is 2, and the value of 2 is saved again to the memory address where P resides. Visible throughout the execution, the change is the value of the memory address where the variable p resides

In this code, Python is actually now executing an object in memory that creates a 1 and points p to it. When performing an addition operation, a new object of 2 is actually obtained with the addition operation, and P is pointed to the new object. Visible throughout the execution, the change is the memory address that P points to
root cause of default value traps for function parameters

A word to explain: the default value of the parameters of the Python function is bound at compile time.

Now, let's start with an excerpt to analyze the cause of this trap in detail. Here is an explanation of why the excerpt from the Python Common gotchas:

Python ' s default arguments are evaluated once when the "function is defined", not the "the" "function is called" (like it Is in say, Ruby). This means so if you use a mutable default argument and mutate it, your would and have mutated the object for all future Calls to the function as.

Visible if the default value of the parameter is determined at the compile stage of the function compilation. After all the function calls, if the argument does not show the given value, then the so-called parameter default value is just a pointer to the object that already exists in the compile phase. If the function is called, the specified incoming parameter is not displayed. Then all this argument in this case will exist as an alias for the object created at compile time.

If the default value of the parameter is an immutable (imuttable) value, if the parameter is modified in the body of the function, then the argument will point back to another new immutable value. And if the parameter defaults are a variable object (muttable), as in the first instance of this article, then the situation is rather bad. All the changes in the body of the function to this parameter are actually modifications to the object that has been identified in the compile phase.

For such a trap there are also special hints in the official Python documentation:

Important warning:the Default value is evaluated only once. This makes a difference "when" the default is a mutable object such as a list, dictionary, or instances of most classes. For example, the following function accumulates the arguments passed to it on subsequent calls:
How to avoid this trap to bring no trouble

Of course, the best way is not to use mutable objects as default values for functions. If this is the case, the following is a solution. As an example of the requirements at the beginning of the article:

def generate_new_list_with (My_list=none, Element=none):
  if My_list is None:
    my_list = []
  my_list.append ( Element) return
  My_list

Why does Python have to be so designed?

The answer to this question can be found in the StackOverflow. The most important part of the answer to the most votes here is excerpted as follows:

Actually, this isn't a design flaw, and it's not because of internals, or performance.

The It comes simply from the fact to functions in Python are first-class, and is only a objects of code.

As soon as you get to the way, then it completely makes Sense:a function is a object being evaluated on its Definition Default parameters are kind of "member data" and therefore their the ' may ' change from one called to the other–exactly as In all other object.

In any case, Effbot has a very nice explanation of the reasons for this behavior in Default Parameter Values in Python.

I found it very clear, and I really suggest reading it for a better knowledge the how function objects work.

In this response, the answer is that the function is an internal-level object, given the way the Python compiler is implemented. The default value of the parameter is the property of this object. In any other language, object properties are bound when the object is created. Therefore, it is not surprising that the function parameter defaults are bound at compile time.
However, there are a number of other respondents who do not buy into the belief that even first-class object can be bound at execution time using the closure method.

This isn't a design flaw. It is a design decision; Perhaps a is one, but not a accident. The state thing are just like any other closure:a closure are not a function, and a function with mutable default argument is not a function.

There is even a rebuttal to the implementation of logic, simply from the design point of view: As long as it is against the program ape basic Thinking Logic behavior, are design flaws! Here are some of their arguments:

> Sorry, but anything considered "the biggest WTF in Python" are most definitely a design flaw. This is a source of bugs for everyone at some point, because no one expects that behavior at First–which means it should Not have been designed the way to begin with.

The phrases "This are not generally what were intended" and "a way around this is" smell like they ' re documenting a design f Law.

Well, the answer to this question will always be a mystery if there is no personal Ching from the Python author.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.