stay Python When you define a function in , You can specify Default parameters
, So you don't have to pass in parameters every time you call the function , And it can simplify our code .
When you define a function , If used Variable type
As a function of Default parameters
, There are often side effects . Look at the following code .
def foo(li=[]):
li.append(1)
print(li)
foo()
foo()
foo()
You may want to get the following result :
[1]
[1]
[1]
But actually , The result is :
[1]
[1, 1]
[1, 1, 1]
According to the results , It seems that every function call ,li
The list records the result of the last call , Instead of using default parameters []
. But every time we call a function , All pass an empty list []
go in , There will be no side effects , To be able to get the results we want right .
def foo(li=[]):
li.append(1)
print(li)
foo([])
foo([])
foo([])
[1]
[1]
[1]
Why did this happen ? In fact, the reason for this problem is Python It is determined by the properties of functions in . Because the function is also object
, and object
You can have your own properties , So functions have their own properties .
When foo
When a function is created , its Default parameters
Has been preserved in its __defaults__
Attribute in . Functions are created only once , Every time after that foo()
When , Will only call functions , It's not going to recreate a function . So the function of Default parameters
It will only be calculated once , No matter how many times it is called later , Default parameters
It's always the same object
.
We use it id()
Function to print out the memory address of the default parameter .
def foo(li=[]):
li.append(1)
print(li, id(li))
foo()
foo()
foo()
[1] 48904632
[1, 1] 48904632
[1, 1, 1] 48904632
It can be seen that , After calling the function three times , It's printed inside li
The address is the same , So they're actually the same object
.
Knowing the cause of the problem , So what if we solve it ? We can use None
As a function of Default parameters
, Calling foo
Function time , Inside the function body, you can judge li
Is it None
To decide if you need to use The default value is
. such , When calling foo()
Function and no arguments are passed , Give again li
Assign a The default value is
that will do .
def foo(li=None):
if li is None:
li = []
li.append(1)
print(li)
foo()
foo()
foo()
[1]
[1]
[1]
So you don't have to worry Variable type
As function Default parameters
Side effects of drug use , It doesn't have to be called every time foo
Functions pass in a parameter , Can solve this problem very well .
therefore , When we define a function Default parameters
when , Should be used as much as possible Immutable type
In order to avoid unexpected side effects . Of course , Unless you know exactly what you need to use Variable type
To achieve certain goals .