第一节 总览
Section I Overview
It is well known that if a function defines a formal parameter, then the parameter must be passed when calling the function, otherwise the system will report an error.
众所周知,如果函数定义了形参,那么调用函数的时候就要传递参数,否则系统将会报错。
#正确的传递参数方式 The right way of passing parameters
In [34]: def ad(a,b):
...: print(a+b)
...:
In [35]: ad(1,2)
3
#错误的传递参数方式 The wrong way to pass parameters
In [34]: def ad(a,b):
...: print(a+b)
In [36]: ad(1)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-36-e6dd8e29e4b8> in <module>()
----> 1 ad(1)
TypeError: ad() missing 1 required positional argument: 'b'
再看如下两个范例:
Look at the following two examples:
我们在函数的参数中加入一个形为*args
的参数:
We add a parameter in the form of * args
to the parameter of the function:
In [23]: def test(a,b,*args):
...: print(a)
...: print(b)
...: print(args)
In [24]: test(1,2)
1
2
()
In [25]: def test(a,b,*args):
...: print(a)
...: print(b)
...: print(args)
In [26]: test(1,2,3,4,5,6)
1
2
(3, 4, 5, 6)
It can be seen that all the additional parameter functions are received and output in tuple mode. Since it is tuple, can we change the output mode?
可见多出来的参数函数以元组方式全部接收并进行了输出,既然是元组,那我们是不是可以改变一下输出方式呢?
In [37]: def test(a,b,*args):
...: print(a)
...: print(b)
...: for t in args:
...: print(t)
...:
In [38]: test(1,2,3,4,5,6)
1
2
3
4
5
6
下面我们再增加一个形参,名为**kwargs
:
Let's add another parameter called ** kwargs
:
In [39]: def test(a,b,*args,**kwargs):
...: print(a)
...: print(b)
...: print(args)
...: print(kwargs)
...:
In [41]: test(1,2)
1
2
()
{}
在只传递了2个参数的情况下,可以看到第四个参数数据的类型是一个字典。
With only two parameters passed, you can see that the type of the fourth parameter data is a dict
.
我们用刚才的方式来调用试试看:
Let's try calling it the way we did just now:
In [42]: test(1,2,3,4,5,6)
1
2
(3, 4, 5, 6)
{}
这时候我们必须要知道的就是如何才能把参数转入字典中呢?
Now what we have to know is how to put the parameters into the dict
?
看如下代码:
Look at the code below:
In [48]: test(1,2,3,4,5,6,7,a23=10,b8="1")
1
2
(3, 4, 5, 6, 7)
{'a23': 10, 'b8': '1'}
现在可以得知,要传递参数到字典中,参数必须满足XX=XX的模式:
Now you can see that in order to pass parameters to the dict
, the parameters must satisfy the mode XX = XX.
第二节 *args 的解包
Section 2 * Args unpacking
上节说到,只要在调用函数的时候,不传递带key
的参数,那所有的参数都将存入到*args
中以元组方式返回。
As mentioned in the previous section, as long as the parameters with key
are not passed when the function is called, all the parameters will be stored in *args
and returned as tuples.
那我们在上面函数定义的代码中稍作改动,让函数在输出 *args
的同时,把 *args
中元素的个数打印出来。
So let's make a slight change in the code defined by the function above so that the function prints out the number of elements in * args at the same time as it outputs * args.
In [81]: def test(a,b,*args,**kwargs):
...: print(a)
...: print(b)
...: print(args,end='')
...: print("-----*args中元素的个数为:"+str(len(args)))
...: print(kwargs)
...:
In [82]: test(1,2,3,4,5,6,7,8,9)
1
2
(3, 4, 5, 6, 7, 8, 9)-----*args中元素的个数为:7
{}
我们把函数调用的代码作一丢丢的改动,再来看输出的情况:
Let's make a little change to the code of the function call, and then look at the output.
In [83]: test(1,2,(3,4,5,6,7,8,9))
1
2
((3, 4, 5, 6, 7, 8, 9),)-----*args中元素的个数为:1
{}
注意到哪里不同了吗?对,仅仅是加了一对括号()
而已。
Notice what's different? Yes, just a pair of parentheses()
.
很好,到这里我们看到了两次“相互对应”的操作,我们调用时传递了7个参数,返回就是7个参数。我们调用时传递了1个参数,返回的也是一个参数。
Well, here we see two "corresponding" operations. We pass seven parameters when we call, seven parameters when we return, one parameter when we call, and one parameter when we return.
但是不要忘了,我们是人类,人类是很懒惰的,所以我们想要做的事情就是:我传递刚才的1个参数给你,但是你要分开来返回给我,因为你是计算机,你要多做一点事情。
But don't forget, we are human beings who are very lazy, so what we want to do is: I pass you a parameter just now, but you have to separate and back it to me, because you are a computer, you have to do more jobs.
什么都不说,就是干!
we will say we will do!
In [84]: test(1,2,*(3,4,5,6,7,8,9))
1
2
(3, 4, 5, 6, 7, 8, 9)-----*args中元素的个数为:7
{}
In [85]:
哈哈哈,这是不是非常懒,只加了一个*
而已!整存零取!
How lazy we are!Only one *
was added.Integral storage and zero fetch.
这就是解包的含义!
That's what unpacking means!
那么我们依葫芦画瓢,再简单看一下dict
的解包是什么样子。首先还是要简单修改一下代码,输出一下dict
的元素的个数。
That's what unpacking means! So let's draw a gourd and see what dict
's unpacking looks like. First, we need to simply modify the code and output the number of dict
elements.
In [85]: def test(a,b,*args,**kwargs):
...: print(a)
...: print(b)
...: print(args,end='')
...: print("-----*args中元素的个数为:"+str(len(args)))
...: print(kwargs,end='')
...: print("-----**kwargs中元素的个数为:"+str(len(kwargs)))
...:
In [86]: test(1,2,3,4,5,6,7,8,9,a1=1,a2=2,a3=3)
1
2
(3, 4, 5, 6, 7, 8, 9)-----*args中元素的个数为:7
{'a1': 1, 'a2': 2, 'a3': 3}-----**kwargs中元素的个数为:3
现在我们把三个键值对打包看一下,对,应该很简单,就是像刚才那么操作,把后面三对参数用{}
括起来,走起!
Now let's take a look at the three key pairs packaged together. Yes, it should be very simple. Just like what we did just now, we can wrap up the last three pairs of parameters with {}
,let's go!
In [87]: test(1,2,3,4,5,6,7,8,9,{a1=1,a2=2,a3=3})
File "<ipython-input-87-879379c68e42>", line 1
test(1,2,3,4,5,6,7,8,9,{a1=1,a2=2,a3=3})
^
SyntaxError: invalid syntax
注意看提示,错误的语法....。仔细一看,对哦,字典内元素的格式应该是XX:XX
才对!立刻改之!
Pay attention to the hints, invalid syntax... Look carefully, yeah, the format of the elements in the dict
should be XX:XX
. Change it immediately!
In [88]: test(1,2,3,4,5,6,7,8,9,{a1:1,a2:2,a3:3})
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-88-3cd0045c1bff> in <module>()
----> 1 test(1,2,3,4,5,6,7,8,9,{a1:1,a2:2,a3:3})
NameError: name 'a1' is not defined
神马情况?怎么又出错了?再看提示,a1没有定义!
What's wrong? Look at the hint , a1 is not defined!
现在我们仔细看上上图正确运行的输出,发现神马没有?
Now let's take a closer look at the previous output that worked correctly, and find out what?
对的!上上图的a1、a2、a3
已经被解读为了字符串' ',而刚才的代码a1被识别为了变量,而且变量没有定义,自然就报错了。那么我们继续来更正这个错误好了,把a1、a2、a3
全部改为字符串类型。
Right! The a1、a2、a3
of the above figure have been interpreted as strings ' ',while the code a1 just now is interpreted as a variable, and the variable is undefined, so the error will occur. So let's go ahead and correct this mistake. Changea1、a2、a3
all to string.
In [89]: test(1,2,3,4,5,6,7,8,9,{'a1':1,'a2':2,'a3':3})
1
2
(3, 4, 5, 6, 7, 8, 9, {'a1': 1, 'a2': 2, 'a3': 3})-----*args中元素的个数为:8
{}-----**kwargs中元素的个数为:0
这次结果好像没有报错唉!打包应该是已经成功了。咦,但是好像还是有一点超出预期。
There seems to be no mistake in this result. Packing should have been successful. Gee, but it still seems a little out of expectations.
我们回忆一下刚才元组的情况,我用()把几个参数括了起来,这个参数包就被*args
接收了,那我把键值对用{}括起来了,应该是被**kwargs
接收才对啊!
Let's recall the tuple case just now. I encapsulated several parameters with () and the parameter package was received by *args
. Then I encapsulated the key-value pairs with {}, which should be received by **kwargs
.
是不是感觉好有道理,又没有什么证据的感觉^_^!
Does it make sense to feel good ?
**kwargs
是什么类型?是dict
,那就是键和值要成对的出现才行。
What is the type of **kwargs
? It's dict
. That's where keys and values appear in pairs.
我们把字典中的键key
和值value
比作一双手套的左右两只,然后再考虑这么一个例子:
We compare the keys key
and value
in the dictionary to the left and right of a pair of gloves, and then consider such an example:
- 你是我的好朋友。
- You are my best friend.
- 有一天你被蜘蛛咬了,长出了六只手,结果到了冬天太冷了,你却不敢出门买手套,于是打发我去帮你买。
- One day you were bitten by a spider and grew six hands. As a result, it was too cold in winter and you dared not go out to buy gloves. So you sent me to buy Gloves for you
- 人生苦短,我用python。额不,我要和你开个玩笑。于是我把买来的三双手套,锁在了一个铁盒子里,交给了你。
- Life is short. I use python. No, I'm kidding you. So I locked the three pairs of gloves I bought in an iron box and gave them to you.
- 亲爱的蜘蛛侠你,瞬间满怒气,开启狂暴怒吼:“贱人!我要的是手套!”
- Dear Spider-Man you, instantly full of anger, open the rage roar: "Bitch! I want gloves!"
- 我:“亲爱的,这是手套lol 在盒子里呢lol”
- Me: "Honey, this is glove in the box."
- 你:“TMD 驼你是他可已经西去了,我马上就会火,打开快点的,以后跟哥混,妹子少不了”
- Iron Man is dead, I will be famous soon.Open it now! If you work for me in the future, I will make you rich, rich and enjoyable. Wives and concubines will flock together.
-我: 好嘞,客官您里屋请,立马开!(此处省略......BYTE)。咋样,合适不? - Okay, wait a moment. How's it going? Are you satisfied?
- 你:好使!
- Fucking good!
okok,我知道太长了又啰嗦,看不懂是吧,好的我们接下来翻译一下:
- 你
**kwargs
是我的好朋友。 - 有一天你被蜘蛛咬了,长出了六只手
key:value,key:value,key:value
,结果到了冬天太冷了,你却不敢出门买手套a1':1,'a2':2,'a3':3
,于是打发我去帮你买。 - 人生苦短,我用python。额不,我要和你开个玩笑。于是我把买来的三双手套
a1':1,'a2':2,'a3':3
,锁在了一个铁盒子里{a1':1,'a2':2,'a3':3}
,交给了你。 - 亲爱的蜘蛛侠你,瞬间满怒气,开启狂暴怒吼:“贱人!我要的是手套
a1':1,'a2':2,'a3':3
!” - 我:“亲爱的,这是手套
a1':1,'a2':2,'a3':3
lol 在盒子里呢{a1':1,'a2':2,'a3':3}
lol” - 你:“TMD 驼你是他可已经西去了,我马上就会火,打开快点的,以后跟哥混,妹子少不了”
- 我: 好嘞,客官您里屋请,立马开
**{a1':1,'a2':2,'a3':3}
!(此处省略......BYTE)。咋样,合适不? - 你:好使!
a1':1,'a2':2,'a3':3
In [85]: def test(a,b,*args,**kwargs):
...: print(a)
...: print(b)
...: print(args,end='')
...: print("-----*args中元素的个数为:"+str(len(args)))
...: print(kwargs,end='')
...: print("-----*kwargs中元素的个数为:"+str(len(kwargs)))
In [90]: test(1,2,3,4,5,6,7,8,9,**{'a1':1,'a2':2,'a3':3})
1
2
(3, 4, 5, 6, 7, 8, 9)-----*args中元素的个数为:7
{'a1': 1, 'a2': 2, 'a3': 3}-----*kwargs中元素的个数为:3
大招就是:**{ }
肚子饿,吃饭去了。