https://blog.csdn.net/qq_32252957/article/details/80887960
https://www.cnblogs.com/beiluowuzheng/p/8461518.html
Python中的*与**操作符使用最多的就是两种用法。
1.用做运算符,即*表示乘号,**表示次方。
2.用于指定函数传入参数的类型的。
*用于参数前面,表示传入的多个参数将按照元组的形式存储,是一个元组;
**用于参数前则表示传入的(多个)参数将按照字典的形式存储,是一个字典。
*args必须要在**kwargs,否则将会提示语法错误"SyntaxError: non-keyword arg after keyword arg."
def func(*args):
print(type(args))
for index, item in enumerate(args):
'''
enumerate()是python的内置函数
对于一个可迭代的(iterable)/可遍历的对象(list, str,tuple),enumerate将其组成一个索引序列,利用它可以同时获得索引和值
>>> list1 = ['life', 'is', 'too', 'short', 'you', 'need', 'python.']
>>> for index, item in enumerate(list1):
... print(index, item)
...
0 life
1 is
2 too
3 short
4 you
5 need
6 python.
'''
# 下面的参数化打印的教程待会儿写,可以直接搜python format。
print("{}:{}".format(index, item))
def function(**kwarg):
print(type(kwarg))
for key, value in kwarg.items():
print("{}:{}".format(key, value))
def main():
func("python", "golang")
function(a = "python", b = "golang")
if __name__ == '__main__':
main()
'''
结果:
0:python
1:golang
a:python
b:golang
[Finished in 0.5s]
'''
参考的这篇博客基本上把最重要的信息讲清楚,且演示出来了。
因为最近在看别人的代码,发现用了很多的kwargs,但是之前看Python的基础教程时,很少遇到这东西,这次需要系统的拿出来练习一下。
我们来看看这两个关键词, args是arguments(参数)的缩写,kwargs是key word arguments的缩写,从字面意思就能看出来,kwargs对应的就是字典中的key和值,因此也可以便于记忆。
另外,我们需要第三个实验,就是即有*args,又有kwargs,还有普通的参数,需要明白这三者之间的顺序。以及对应的打印展示:
>>> def foo(*args):
... print(args)
...
>>> foo("fruit", "animal", "human")
('fruit', 'animal', 'human')
>>> foo(1, 2, 3, 4, 5)
(1, 2, 3, 4, 5)
>>> arr = [1, 2, 3, 4, 5] # 如果我们希望将一个数组形成元组,需要在传入参数的前面 加上一个*
>>> foo(arr)
([1, 2, 3, 4, 5],)
>>> foo(*arr)
(1, 2, 3, 4, 5)
>>> def foo(**kwargs):
... for key, value in kwargs.items():
... print("%s=%s" % (key, value))
...
>>> foo(a=1, b=2, c=3)
a=1
b=2
c=3
>>> def foo(*args, **kwargs):
... print("args:", args)
... print("kwargs:", kwargs)
...
>>> foo(1, 2, 3, a=1, b=2)
args: (1, 2, 3)
kwargs: {'a': 1, 'b': 2}
>>> arr = [1, 2, 3]
>>> foo(*arr, a=1, b=2)
args: (1, 2, 3)
kwargs: {'a': 1, 'b': 2}
>>> def foo(name, *args, middle=None, **kwargs):
... print("name:", name)
... print("args:", args)
... print("middle:", middle)
... print("kwargs:", kwargs)
...
# 第一个hello没有指定形参,直接被name捕获
# 剩下的才会被*args捕获,但是由于没有指定middle的值,因此采用了默认值
# 剩下的都被**kwargs捕获了。
>>> foo("hello", 1, 2, 3, a=1, b=2, c=3)
name: hello
args: (1, 2, 3)
middle: None
kwargs: {'a': 1, 'b': 2, 'c': 3}
# 第二次测试,hello仍然被name捕获
# 123被*args捕获
# 因为指定了middle值,因此不是默认值。
# 剩下的仍然被**kwargs捡垃圾
>>> foo("hello", 1, 2, 3, middle="world", a=1, b=2, c=3)
name: hello
args: (1, 2, 3)
middle: world
kwargs: {'a': 1, 'b': 2, 'c': 3}
# 这里的第三个实验,才是精髓;
# 先创建一个字典,里面有五个键值对,将这字典传入函数中。
# 函数会先寻找name这个键的值,为hello;
# 接下来因为没有元组,因此args为()
# 再来寻找middle这个键值,找到了值为world
# 剩下没人要的都被存到了kwargs里面了。
>>> my_foo = {"name": "hello", "middle": "world", "a": "1", "b": "2", "c": "3"}
>>> foo(**my_foo)
name: hello
args: ()
middle: world
kwargs: {'a': '1', 'b': '2', 'c': '3'}
再加上我自己的一些探索:
1.定义的字典顺序打乱对结果的影响;
2.传入字典的时候,不加**有何区别
def dict_foo(name, *args, middle=None, **kwargs):
print("name:", name)
print("args:", args)
print("middle:", middle)
print("kwargs:", kwargs)
print("-"*20)
for k, v in kwargs.items():
print("{}:{}".format(k, v))
## 打印结果----
name: {'middle': 'world', 'name': 'hello', 'a': 1}
args: ()
middle: None
kwargs: {}
--------------------
name: hello
args: ()
middle: world
kwargs: {'a': 1}
--------------------
a:1