Default python parameter problems traps, python traps
A common trap in python is the default parameter of functions. As follows:
def func(mylist = []): mylist.append(1) return mylist
The following execution results are as follows:
print func()print func()print func()print func(['a'])print func()
The result is as follows:
[1][1, 1][1, 1, 1]['a', 1][1, 1, 1, 1]
As a result, the first three items show that if no parameter is specified, the called mylist is the same object each time a function is called. This is because the default parameter of the function. When the code is compiled into PyCodeObject, an object pointer has been created and is stored in func_default of the function. During code execution and function call, if no parameter is specified, the parameter variable is the object specified by the variable pointer in the code compilation phase.
print func.func_default
The result is:
([1, 1, 1, 1],)
The default parameters are divided into two types:
The default parameter value is an unchangeable object.
At this time, the function func_default always points to the unchanged object. If the variable is modified inside the function, the default parameter points to a new immutable object.
However, func_default remains unchanged. Every function call Reads func_default, so every execution is the same.
In [30]: def func2(var = 1): ....: var += 1 ....: return var ....: In [31]: func2()Out[31]: 2In [32]: func2()Out[32]: 2In [34]: func2.func_defaultsOut[34]: (1,)
The default parameters are variable objects, such as list, dict, and class.
In this case, if the object indicated by the pointer is modified in the function (no new object is created), func_default will change. This is why the mylist changes. Let's look at the example below ,:
In [35]: def func (mylist = []):...: mylist = [] # A new object is created here, mylist. append (1) return mylistIn [44]: func () Out [44]: [1] In [45]: func. func_defasosout [45]: ([],)
Because an object is created, mylist only exists as the alias of a newly created object, and the modification later has nothing to do with func_default.
An application with default parameters
Let's take a look at the following classic example:
def outer(): res = [] for i in range(4): def inner(j): return j * i res.append(inner) return resprint [m(2) for m in outer()]
# Simple version:
def multipliers(): return [lambda x : i * x for i in range(4)]print [m(2) for m in multipliers()]
The result is [6, 6, 6] instead of [0, 2, 4, 6], because of the delayed binding of the closure. In addition, the function is bound to a variable rather than a numerical value. When the loop ends, the value of I is 3, and the result is 6. A solution is to bind the value with the default parameter. The following changes:
def outer(): res = [] for i in range(4): def inner(j, i = i): return j * i res.append(inner) return resprint [m(2) for m in outer()]
# Simple version:
def multipliers(): return [lambda x, i = i : i * x for i in range(4)]print [m(2) for m in multipliers()]
In this way, the default parameters are written to func_default of the function during code compilation, and can be bound to 0, 1, 2, and 3. The result is naturally
[0, 2, 4, 6]
This is an application of the default parameter.
There is also a method for modifying the generator.
Def multipliers (): return (lambda x, I = I: I * x for I in range (4) # change to generator print [m (2) for m in multipliers ()]
Articles you may be interested in:
- Python implements partial change method default parameters
- Describes the default parameters in Python functions.
- Use partial in Python to change the default parameter instance
- Explanation of default parameters in Python