write sth. upfront
It's not uncommon to read code that contains this*args
cap (a poem)**kwargs
The expression:
For example, what should this output?
def foo(*args): print(args) foo(1, 2, 3, 4, 5)
What about this one?
def foo(a, *args): print('a:', a) print('args:', args) foo(1, 2, 3, 4, 5)
And this?
def bar(a,b,c): print(a,b,c) bar(*[1,2,3])
Huh? How did the ∗ sign appear in front of a list? Is this correct?
*args
cap (a poem)**kwargs
, as well as separate *, ** what exactly does it do? What is the principle? Read this article and you'll understand completely!
*args
There are two components as -*
cap (a poem)args
. The point here is that*
。
So to be clear.*args
We're going topursue sth. back to its origins--Understanding*
The role of the
Here's the blackboard, here's the kicker, and this is what many blogs write about that don't: the role of ∗, there are 2 - the packing parameter (pack) and the unpacking parameter (unpack)!
*argc
Packing parameters
Example 1:
def foo(*number): print(number) foo(1, 2, 3, 4, 5)
(1, 2, 3, 4, 5)
What do we see? The function was given 5 arguments, it ran successfully, and the output was composed of the argumentstuple。
We know that if number is not preceded by the ∗ sign, then it is clear that foo() can only take 1 argument, and it will report an error if more or less arguments are given. With ∗, it will run successfully.
So what's the principle?
The answer is that ∗ takes multiple arguments accepted by the function foo()1,2,3,4,5
Packed into a tuple.(1,2,3,4,5)
which is assigned to the formal parameter number.
We can verify that:
Example 2:
def foo(*number): for i in number: print(i) print(type(number)) foo(1, 2, 3, 4, 5)
1
2
3
4
5
<class 'tuple'>
As you can see from Example 2, number is indeed given to the(1,2,3,4,5)
This real parameter.
Speak with reason, for more details seeOfficial python documentation, stick a picture over here:
Example 3:
def foo(a, *number): print('a:', a) print('number:', number) for i in number: print(i) print(type(number)) foo(1, 2, 3, 4, 5)
a: 1 number (2, 3, 4, 5) 2 3 4 5 <class 'tuple'>
As you can see from Example 3, the real parameter accepted by number becomes(2,3,4,5)
The first parameter1
formal parametera
Acceptance gone.
So here we can give the full version of the ∗-role:
The role of ∗: when a function accepts real parameters, it assigns them to the function's formal parameter in order, and if it encounters a formal parameter with ∗, then the real parameters that have not yet been assigned are packed (pack) in the form of a tuple, and assigned to that formal parameter with ∗.
It can be verified with a few more examples:
Example 4:
def foo(a, b, *number): print('a:', a) print('b:', b) print('number:', number) for i in number: print(i) print(type(number)) foo(1, 2, 3, 4, 5)
a: 1 b: 2 number: (3, 4, 5) 3 4 5 <class 'tuple'>
Example 5:
def foo(a, b, *number, c): print('a:', a) print('b:', b) print('c:', c) print('number:', number) for i in number: print(i) print(type(number)) foo(1, 2, 3, 4, 5)
Traceback (most recent call last): File "C:/Users/PycharmProjects/untitled10/", line 11, in <module> foo(1, 2, 3, 4, 5) TypeError: foo() missing 1 required keyword-only argument: 'c'
Note that in Example 5 I specifically looked for an example that reported an error. Analyze for yourself why the error is reported. The answer is that the argument before c with ∗ accepts the rest of the real parameters, and c is not passed a real parameter!
Up to this point, the packing of ∗ (pack) It explains it all.
And a little tail:argsWhat is it?
The answer is:argsIt's just a convention to write a formal parameter, and it's fine if you write it as something else, but it's not good for standardizing the form. Like in our example, we use number all the time, and it works fine.
splitting parameter
Example 6:
def bar(a,b,c): print(a,b,c) bar(*[1,2,3])
1 2 3
As you can see, ∗ is not used in a function definition this time, but in a function call. What does it do in this example?
The answer is: take the packed real parameters (tuples or lists), unpack them into individual ones, and assign them in turn to the formal parameters of the function.
In this example, the packed real parameter[1,2,3]
is split, with 1 assigned to form parameter a, 2 to form parameter b, and 3 to form parameter c.
∗ The role of splitting is as simple as that. Understand the principle, and everything else is the same. Come up with two questions to practice:
Exercise: which of the following 3 programs works?
Example 7:
def bar(a,b): print(a,b) bar(*[1, 2, 3])
Example 8:
def bar(a, b, c, d): print(a, b, c, d) bar(*[1, 2, 3])
Example 9:
def bar(a, b, c, d=10): print(a, b, c, d) bar(*[1, 2, 3])
The answer is that only Example 9 works. This is because, according to the principles we talked about, the real parameter 3 of Example 7 has no corresponding formal parameter to accept, and the formal parameter d of Example 8 has no real parameter to assign.
**kwargs
Packing parameters
the top*args
I've learned it.**kwargs
And it's easy to understand.**kwargs
There is also a two-part composition for -**
cap (a poem)kwargs
. The point here is ∗∗. That's right.kwargsJust a convention to write, no other special meaning, change the other also used, but for code readability, it is best to use the convention.
Again, ∗∗ has two roles - packing parameters (pack) and unpacking parameters (unpack)!
But the difference is still there, simply put:
Packing:*args
is a combination of multipleposition parameterpacktuple,**kwargs
is a combination of multipleKeyword parameterspackdictionaries。
Unpacking:*args
is to split the packed parameters into individual ones and assign them to the function's formal parameters in turn.**kwargs
is to split the dictionary's keys into individual ones and assign them sequentially to the function's formal parameters.
Example 10
def bar(**number): print(number) bar(a=1, b=2, c=3)
{'a': 1, 'b': 2, 'c': 3}
splitting parameter
Example 11
def bar(a, b, c): print(a,b,c) bar(**{'a': 1, 'b': 2, 'c': 3})
1 2 3
Note that there is a caveat here, that is, when using the ∗∗ way to disassemble the dictionary to assign a value to a formal parameter, you need the key name of the dictionary and the formal parameter of the function to be all the time, or else it will report an error, try it by yourself and you will know.
positional parameters, keyword parameters, the*args
,**kwargs
Mixing is done in a certain order, and I'm specifically not writing about it here. I'm not going to write about it here, because it shouldn't be a problem in itself, it's a basic skill that you should lay down when you learn functions. If you really need it, you can look it up yourself to deepen your impression, which is better than just reaching out to me.
to this article on Python *args and **kwargs understanding of the article is introduced to this, more related Python *args and **kwargs content, please search for my previous articles or continue to browse the following related articles I hope you will support me in the future more!