栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

python中 *、*args 、 **、 **kwargs用法详解

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

python中 *、*args 、 **、 **kwargs用法详解

前置知识:
  1. python中函数调用时,传入的参数叫做实参,实参又分为位置参数(positional argument) 和关键字参数(keyword argument)。位置参数就是直接传值,按照其位置分配给函数定义中的形参,比如下面例子中函数调用时fun(1,2, c=5)中的1,2就是传入的位置参数。关键字参数是按照函数定义中形参的名字来传值,比如 下面例子中函数调用时传入的 “c=5”就是关键字参数。
  2. 形参列表(formal parameter list):形参是指在函数定义时设置的参数,以下面函数定义为例, [a , b, c] 就是形参列表。
>>>def fun(a, b, c, *args, **kwargs):
>>>	    print(a,b,c)
>>>	    print(args)
>>>	    print(kwargs)

>>>fun(1,2,c=3)
''' 
1 2 3
()
{}
'''
* 与 *args
  1. 在函数调用以及平时使用时, *用于将 tuple / list / str 解包(unpack),解包后的每个元素都作为单独的一个参数传入函数内部。见下面例子所示。
  2. 在函数定义时,*args的作用就是将未来被调用时多传进来的位置参数打包成一个名为args的元组,在函数内部使用。 本质的操作应该是:“ * args = 多余的位置参数”,*又具有解包的功能,这样就实现了将多余的位置参数放置在了args这个包中。以本文中fun函数的定义为例, 见如下代码所示。
>>>	fun(1,2,3,4,5)
'''
1 2 3
(4, 5)
{}
'''
>>>	d = (2,3)
>>>	print(*d)
''' 2 3 '''
>>>	fun(1,*d)
'''
1 2 3
()
{}
'''
>>>	fun(1,2,*d)
'''
1 2 2
(3,)
{}
'''
** 和 **kwargs
  1. 在函数调用时以及平常使用时, ** 用于将 dictionary字典 解包(unpack),然后将字典中的每一项作为单独的关键字参数传入函数内部。注意:字典中每一项的键值必须对应于函数定义中的形参名字
  2. 在函数定义时, **kwargs用于接受在调用时超过形参列表数量的所有关键字参数,并将他们打包成一个字典 kwargs传入函数内部使用,具体的过程与*args相似。同样以fun函数为例来分析,见如下代码。
>>> e ={"b":2,"c":3}
>>> fun(1,**e)
'''
1 2 3
()
{}
'''
>>>	f = {"c": 2, "d": 3}
>>>	fun(1, 2, **f)
''' 2 3 '''
>>>	fun(1,*d)
'''
1 2 2
()
{'d': 3}
'''
代码案例

当我们继承一个类并覆盖继承类的某些方法时,我们应该使用 *args 和 **kwargs 并将接收到的位置和关键字参数传递给父类方法。

class Model(object):
    def __init__(self, name):
         self.name = name
    def save(self, force_update=False, force_insert=False):
        if force_update and force_insert:
             raise ValueError("Cannot perform both operations")
        if force_update:
            #Update an existing record
            print("Updated an existing record")
        if force_insert:
            #Create a new record
            print("Created a new record")

class ChildModel(Model):
    def save(self, *args, **kwargs):
        if self.name == "abcd":
            # 下面这句是python2的写法,在python3中可直接写成:super.save(*args, **kwargs)
            super(ChildModel, self).save(*args, **kwargs)
        else:
            return None       

这里创建了两个类,一个父类 Model,一个子类 ChildModel 继承 Model。因此,我们需要从ChildModel的save()方法中调用父类的“ save()”方法。另外,子类的()方法,即ChildModel中的save()应该能够接受Model中save()接受的任何参数,并且必须将这些参数传递给父类Model的 save()中。因此,我们在子类 save()方法的参数列表中有 *args和 **kwargs,以接收形参列表以外的任何位置参数或关键字参数。

>>> c=ChildModel('abcd')
>>> c.save(force_insert=True)
'''Updated an existing record'''

首先创建一个 ChildModel 类对象 c,名字为 “abcd"。c.save()是调用ChildModel类的save()方法,将force_insert=True 打包成一个字典kwargs,因为名字==“abcd",所以 执行super(ChildModel, self).save(*args, ** kwargs)。 首先通过super(ChildModel, self)找到ChildModel的父类Model,然后使用.save(*args, **kwargs)调用父类中的save方法,这里面的 * 和 ** 是用来解包的,**将字典kwargs解包成一个个的关键字参数,传入进父类的save()中

参考:Understanding ‘*’, ‘*args’, ‘**’ and ‘**kwargs’

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/968305.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号