bigtreei

python中’*’和’**’的使用分两个方面,一个是计算,另一个是参数传递过程中元素的打包和解包。 

计算方面

‘*’和’**’在python中最常见的作用分别是‘相乘’和‘乘幂’,如下:

>>> a  = 2
>>> b = 3
>>> c = 5*6
>>> d = 4**3
>>> e = a*b
>>> f = a**b

传递、打包、解包方面

函数的可变参数

  • 对函数传递的参数进行打包(成元组tuple或字典dictionary)和拆解(分解成单个元素),其中元组的打包和解包使用单星号‘*’,字典的打包和拆解使用’**’。 
  • 打包,就是将传递给函数的任意多个(也可以是零个)非关键字参数/关键字参数打包成一个元组/字典(元组只能接收非关键字参数,字典只能接收关键字参数) 

当函数的参数前面有一个星号*的时候表示这是一个可变的位置参数,两个星号**表示是可变的关键字参数。

def foo(*args, **kwarg):
    for item in args:
        print item

    for k,v in kwarg.items():
        print k,v
    print 30*\'=\'
if __name__ == \'__main__\':
    foo(1, 2, 3, a=4, b=5)
    foo(2, 3, a=4, b=5, c=1)

输出如下:

C:\Users\BigTree\AppData\Local\Programs\Python\Python36\python.exe "C:/Python S8/develops/Day 2 控制语句/星号用法.py"
1
2
3
a 4
b 5
**************************************************
2
3
a 4
b 5
c 1
**************************************************

Process finished with exit code 0

这样我们可以传入任意个数的参数。

解包/打散(unpack)参数

  • 拆解,就是将传递给函数的一个列表、元组或字典拆分成独立的多个元素然后赋值给函数中的参变量(包括普通的位置参数,关键字参数,元组也即*非关键字参数,字典也即**关键字参数)。
  • 在解字典时会有两种解法,一种使用*解,解出来传给函数的只有键值(.key)另一种是用**解,解出来的是字典的每一项。 

星号*把序列/集合解包(unpack)成位置参数,两个星号**把字典解包成关键字参数

下面通过示例来进一步加深理解:

def foo(*args, **kwarg):
    for item in args:
        print(item)
    for k,v in kwarg.items():
        print(k, v)
    print(\'*\' * 50)

if __name__ == \'__main__\':
    #foo(1, 2, 3, a=4, b=5)
    #foo(2, 3, a=4, b=5, c=1)
    v = (1, 2, 4)
    v2 = [11, 15, 23]
    d = {\'a\':1, \'b\':12}
    foo(v, d)
    foo(*v, **d)
    foo(v2, d)
    foo(*v2, **d)

输出如下:

C:\Users\BigTree\AppData\Local\Programs\Python\Python36\python.exe "C:/Python S8/develops/Day 2 控制语句/星号用法.py"
(1, 2, 4)
{\'a\': 1, \'b\': 12}
**************************************************
1
2
4
a 1
b 12
**************************************************
[11, 15, 23]
{\'a\': 1, \'b\': 12}
**************************************************
11
15
23
a 1
b 12
**************************************************

Process finished with exit code 0

上面的示例中如果v、v2、d没有加星号那么就当成了一个参数传递给了函数,如果加了星号那么就会解包后传递给函数。

foo(*d, **d)等价于foo(1, 2, 4, a=1, b=12)

几个注意点

可变位置参数*args是一个元组,是不可修改的。

>>> def foo(*args):
...     args[0] = 5
... 
>>> foo(1, 2, 3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in foo
TypeError: \'tuple\' object does not support item assignment
>>> l = [1, 2, 3]
>>> foo(*l)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in foo
TypeError: \'tuple\' object does not support item assignment

无论我们怎么传入参数,args都是一个tuple类型,不能进行修改。 
对于字典类型的如果只使用一个型号*那么传入的只是字典的键。

>>> def foo2(*args, **kwarg):
...     print args, kwarg
... 
>>> d = {\'a\':1, \'b\':2, \'c\':3}
>>> foo2(*d)
(\'a\', \'c\', \'b\') {}
>>> foo2(**d)
() {\'a\': 1, \'c\': 3, \'b\': 2}
 
 

分类:

技术点:

相关文章:

  • 2022-12-23
  • 2021-09-30
  • 2021-12-21
  • 2022-12-23
  • 2022-12-23
  • 2021-12-23
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-09-22
  • 2023-03-19
  • 2022-12-23
  • 2021-12-09
相关资源
相似解决方案