12 Respuestas
+ 6
b is a list
Variable a keeps moving to the list
print(func(3,[]))
Here, we're passing a new, empty list [] as the argument for b. This overrides the default argument. b becomes [3] but does not replace b list.
https://sololearn.com/compiler-playground/ce0o4o5JlF0r/?ref=app
+ 5
def func(a, b=[]):
Under behavior most people expect, the declaration of func would be evaluated at compile, and the evaluation of the default argument would be evaluated at execution.
However the Python devs wanted to avoid split evaluation for function definitions with default arguments.
Following one of the language goals, the devs wanted the entire line to be evaluated in one go meaning the default argument is also evaluated at compile.
This only becomes a problem for MUTABLE default arguments, turning them into effectively static function variables folks are familiar with in other languages.
To avoid this issue, the suggested work-around is
def func(a, b=None):
if b is None:
b = []
b.append(a)
return b
None is IMMUTABLE.
b = [] is not just updating the default argument, but completely replacing it since None can not be changed.
So b will always start as None for every function call which relies on the default argument.
+ 4
I, too, am surprised by the result, because I expected the default parameter to be newly created in each call. I had Gemini explain it:
"The behavior can be surprising and lead to unintended side effects if you're not aware of how default arguments work with mutable objects. It violates the principle of least astonishment. People often expect default arguments to be re-initialized each time the function is called, as is the case in many other programming languages.
**Default Argument Evaluation:** Default arguments in Python functions are evaluated *only once*, when the function is defined, not each time the function is called."
Well, now it makes sense.
+ 4
Wong Hei Ming great link 👍
Mira Wadhwa
"Don’t Use Mutable Values for Default Arguments"
Also be careful when passing lists into arguments.
Because they are cached in memory and acts like global variables, the items of the list will be updated, so you should be careful about that.
do this instead:
def func(a, b=None): # do not use b=[] here
if b is None:
b = [] # assign b here instead
b.append(a)
return b
print(func(1))
print(func(2))
print(func(3, []))
print(func(4))
print(func(7, [5,6]))
+ 3
You can find out _what_ the output is by running the code on sololearn playground.
_Why_ the output is like this, is a different question. Think about it like this: What does "b" refer to in each function call? What do you know about how Python handles lists?
+ 3
BroFar Have a look at the last printed list. Consider letting func() return b, id(b), for instance.
+ 3
Brian
I remember reading something about this behavior.
https://inventwithpython.com/beyond/chapter8.html#calibre_link-174
+ 2
Is this a quiz or a genuine question?
+ 2
Lothar
print(func(3, [])) # Third call. Here, you explicitly pass a new empty list.
# ic| a: 3
# ic| b: [3]
# [3]
+ 1
A genuine question. Hoping answer with explanation
+ 1
Um im did not see that one
0
Where is it i dont see it and i finished intro to phyton