Python中的*和**(转载+合成---一文搞懂Python的*传参)

Python中的*和**(转载)

参考链接:

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,还有普通的参数,需要明白这三者之间的顺序。以及对应的打印展示:

1. 单独使用*args

>>> 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)

2. 单独使用**kwargs

>>> 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

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}

4.混合使用+普通参数+默认参数

>>> 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

你可能感兴趣的:(Python,学习笔记)