Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >[949]python不定长参数*args和**kwargs

[949]python不定长参数*args和**kwargs

作者头像
周小董
发布于 2021-03-08 14:16:35
发布于 2021-03-08 14:16:35
3.7K10
代码可运行
举报
文章被收录于专栏:python前行者python前行者
运行总次数:0
代码可运行

python语言写成的模块中的函数里,常常可以看到函数的参数表列里面有这两个参数,形如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def some_function(*args, **kwargs):
    to do list
    return 0

首先,解释星号的作用,一个星号*的作用是将tuple或者list中的元素进行unpack,分开传入,作为多个参数;两个星号**的作用是把dict类型的数据作为参数传入。

kwargs是keyword argument的缩写,args就是argument。我们知道,在Python中有两种参数,一种叫位置参数(positional argument),一种叫关键词参数(keyword argument),关键词参数只需要用 keyword = somekey 的方法即可传参,而位置参数只能由参数位置决定。这也就决定了位置参数一定要在前面,否则关键词参数数量的变化(比如有些kwargs有默认值因此没有传参或者在后面传参的),都会使得位置无法判断。因此常见的也是*args**kwargs 前面。

题目描述:

1、怎么理解不定长参数? 2、*args**kwargs 是什么意思?为什么要使用它们?

答案要点如下:

1、函数参数可为分如下几种:必选参数、默认参数、可变参数、命名关键字参数和关键字参数

2、当我们在定义和调用一个函数时,如果包含所有的参数类型,则必须按照:必选参数、默认参数、可变参数、命名关键字参数和关键字参数的顺序。但是在实际开发中,不建议包含过多的参数类型,会影响代码的可读性

3、必选参数很简单,就是函数中必须要接受的参数

4、默认参数,即给参数赋一个默认值,我们在传递时,可省略对该参数的传值操作。如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def print_test(title, msg="world"):
    print(title, msg)

print_test("hello") # hello world
print_test("hello", "demon") # hello demon
print_test("hello", msg="demon") # hello demon

# 错误调用示例
# print_test( msg="demon","hello") # 这样是不对的

5、可变参数,在定义函数是用 *args 来接受,其中 * 是规定的,args可用其他名称替换,但一般习惯用 args 来表示。可变参数在传入函数后,被封装成一个 tuple 来进行使用。所以我们在函数内部,可以通过操作 tuple 的方法来操作参数,示例如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def print_numbers(*args):            
    print(type(args))  # tuple
    for n in args:
      print(type(n))   # int

print_numbers(1, 2, 3, 4)

6、如果在函数外已经得到一个 list 或者 tuple,想调用一个可变参数,也可以用 *+变量名 的形式进行调用,(这种用法有点类似 C语言 中的指针),示例如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def print_numbers(*args):            
    print(type(args))  # tuple
    for n in args:
      print(type(n))   # int

l = [1, 2, 3, 4]
print_numbers(*l)  # *l,等价于 print_numbers(1, 2, 3, 4)
print_numbers(l)   # 将 l 作为一个整体传入,这样函数接受到的其实只有一个参数,且参数类型为 list

7、关键字参数使用 kwargs 来标识,是规定,而kwargs可替换,它将不定长参数转换为 dict 传入函数。它用于扩展函数的功能。比如我们要实现用户注册,有必输项和非必输项,这些非必输项就可以用关键字参数来接受。示例如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def register(name, email, **kwargs):
    print('name:%s, age:%s, others:%s', (name, email, kwargs))

register("demon", "1@1.com") # name:%s, age:%s, others:%s ('demon', '1@1.com', {})
register("demon", "1@1.com", addr="shanghai") # name:%s, age:%s, others:%s ('demon', '1@1.com', {'addr': 'shanghai'})

8、如果函数外已经获得一个 dict ,想进行函数调用,只需用 **+变量名 传入即可。并且 dict示例如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def register(name, email, **kwargs):
    print('name:%s, age:%s, others:%s', (name, email, kwargs))

d = {"addr":"shanghai"}
register("demon", "1@1.com", **d)

d = {"name":"yrr", "email":"1@1.com", "addr":"shanghai"}
register(**d)

d = {"email":"yrr", "name":"1@1.com", "addr":"shanghai"}
register(**d)

9、命名关键字参数用于限制调用函数可传入的属性。这里的限制是假限制,因为仍然可以传入,只是函数体中对限制外的参数不作任何处理。命名关键字参数用一个 * 号分隔,* 后面的参数都被视为命名关键字参数。如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def person(name, age, *, city, job):
    print(name, age, city, job)

10、如果函数中已经有了一个可变参数的定义,后面的命名关键字参数则不需要再添加 * ,如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def person(name, age, *args, city, job):
    print(name, age, args, city, job)

11、关键字参数和命名关键字参数在调用时必须用 key=value 的形式来调用,这类参数我们称之类名称参数,而不需要指定参数名称的参数,也称为位置参数。必输参数和可变参数都可以通过位置参数来匹配。如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def register(name, email, **kwargs):
    print('name:%s, age:%s, others:%s', (name, email, kwargs))

# 错误调用:
register("123","123","123")
# 它会把第三个参数 "123" 也当成是位置参数传入函数
# 相当于调用了一个有三个必输参数的函数
# 而实际的 register 函数只接受两个必输参数
# 因此会报错:TypeError: register() takes 2 positional arguments but 3 were given

12、最后一个比较特殊,也是一个结论:对于任意函数,都可以通过func_name(*args, **kw)的形式来进行调用其中 args 是一个已经获得的列表或者元组,而 kw 是一个已经获得的字典。列表传入会按顺序对必输参数赋值,多余的参数会当成可变参数传入,而字典传入会根据 key 来匹配所有参数。如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def test1(a, b, c=0, *args, **kwargs):
    print('a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kwargs)

def test2(a, b, c=0, *args, d, **kwargs):
    print('a =', a, 'b =', b, 'c =', c, 'd =', d, 'args=', args, 'kw =', kwargs)

# 定义一个元组和字典用作参数传入
args = (1, 2, 3, 4)
kw = {'d': 99, 'x': '#'}

test1(*args, **kw)
# a = 1 b = 2 c = 3 args = (4,) kw = {'d': 99, 'x': '#'}
test2(*args, **kw)
a = 1 b = 2 c = 3 d = 99 args= (4,) kw = {'x': '#'}

参考:https://zhuanlan.zhihu.com/p/70649428 https://blog.csdn.net/edogawachia/article/details/80588858 https://www.xin3721.com/pythonNew/python22337.html

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/03/05 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
1 条评论
热度
最新
第7处 的格式化字符串好像有问题 print('name:%s, age:%s, others:%s', (name, email, kwargs)) 应该是 print('name:%s, age:%s, others:%s',%(name, email, kwargs))
第7处 的格式化字符串好像有问题 print('name:%s, age:%s, others:%s', (name, email, kwargs)) 应该是 print('name:%s, age:%s, others:%s',%(name, email, kwargs))
回复回复点赞举报
推荐阅读
编辑精选文章
换一批
python基础----函数参数
本文介绍了Python函数的参数传递方式,包括直接传入、默认参数、可变参数和关键字参数。直接传入是指将参数作为函数的参数直接传递给函数;默认参数是指在函数定义时,为参数指定一个默认值;可变参数是指在函数定义时,为参数指定一个可接受任意数量的参数;关键字参数是指在函数调用时,使用关键字参数来传递参数。
GavinZhou
2018/01/02
5640
python3_函数
欢迎与我分享你的看法。 转载请注明出处:http://taowusheng.cn/
yifei_
2022/11/14
2550
Python传入参数的几种方法
Python唯一支持的参数传递方式是『共享传参』(call by sharing)
py3study
2020/01/07
4.1K0
【python入门到精通】python核心知识之参数与变量完全解读
上面的函数虽然解决了问题,但是显然不够完美,假设在大部分的调用里,基本都只是求x的2次幂,但 是这个时候我在调用的时候依旧每次都得传n,这就显得有点多余。有没有什么方法可以让我调用的时 候少些一个入参呢?
大数据小禅
2021/12/21
4490
人人都能学会的python编程教程12:函数的参数
Python的函数定义非常简单,也非常灵活。除了正常定义的必选参数外,还可以使用默认参数、可变参数和关键字参数,使得函数定义出来的接口,不但能处理复杂的参数,还可以简化调用者的代码。
JKXQJ
2018/04/18
8736
人人都能学会的python编程教程12:函数的参数
python学习笔记:*args和**kwargs使用原理?
一.*args和**kwargs原理  先看个例子: def test(*args,**kwargs): print("args =",args) print("kwargs =",kwargs) print("----------------------------------") if __name__ == '__main__': test(1,5,94,564) test(a=1,b=2,c=3) test(1,2,3,4,a=1,b=2,c=3)
用户1679793
2018/04/28
1.2K0
Python 函数(一)
函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段;通过函数,可以对特定功能的代码进行封装,实现代码的复用。
AiDBA宝典
2022/02/22
4950
Python基础笔记3
要调用一个函数,需要知道函数的名称和参数,比如求绝对值的函数abs,只有一个参数。可以直接从Python的官方网站查看文档:
py3study
2020/01/03
3740
python函数参数
【总结】默认情况下,参数是通过其位置进行匹配的,从左到右,而且必须精准的传递和函数头部参数名一样多的参数。参数定义的顺序必须是:必选参数、默认参数、可变参数/命名关键字参数和关键字参数。
叶子陪你玩
2020/03/11
9250
Python入门学习(六)
上面函数中, 需要两个参数分别是 x, y. 这两个参数都是必选参数, 缺一不可. pow函数中 x 为底数, y 为指数, 现在我想让指数默认为 2
py3study
2020/01/03
3720
Python参数类型以及常见的坑
这个输出的结果应该是意料之中,现在我们这时候再调用Book()方法,看看会发生什么:
py3study
2020/01/07
1.4K0
浅析Python函数的参数
Python的函数定义非常简单,但灵活度却非常大。除了正常定义的必选参数外,还可以使用默认参数、可变参数和关键字参数,使得函数定义出来的接口,不但能处理复杂的参数,还可以简化调用者的代码。
Go进阶者
2021/03/08
5380
浅析Python函数的参数
【Python】8“函数的参数“
按函数参数顺序传入参数,这样的参数就叫做位置参数。Java的函数中,规定调用者必须按形式参数顺序依次传入参数,这样也可以看做是位置。 案例(幂运算):
肓己
2021/08/12
3740
Python函数参数之全面讲解
Python函数参数 Python函数参数 本文主要介绍Python的函数参数,各种形式的参数。建议动手试试,可以加深理解。 函数参数 定义函数的时候,我们把参数的名字和位置确定下来,函数的接口定义就完成了。对于函数的调用者来说,只需要知道如何传递正确的参数,以及函数将返回什么样的值就够了,函数内部的复杂的逻辑被封装起来,调用者无需了解。 Python的函数定义非常简单,但灵活度却非常大。除了正常定义的必选参数外,还可以使用默认参数、可变参数和关键字参数,使得函数定义出来的接口,不但能处理复杂的参数,还可以
1846122963
2018/03/09
1.4K0
Python 3.6学习笔记(一)
可以看到,注释以#开头,python的变量不需要任何前缀,行结束不需要结束符号,非常符合我们自然语言的阅读和书写习惯。当语句以:结尾时,缩紧的语句视为代码块。
大江小浪
2018/07/24
4700
python函数的参数
对于power(x)函数,参数x就是一个位置参数,当我们调用power(x)函数时,必须传入有且仅有一个参数x
py3study
2020/01/06
9990
Python3 系列之 可变参数和关键字
对于可变参数可以联想到 C# 中的可变参数。可变参数是一个数量不确定的列表集合,可以是 list 类型,也可以是 tuple 类型 我们定义如下代码段:
py3study
2020/01/19
5410
【Python】002-Python函数
在Python中,定义一个函数要使用def语句,依次写出函数名、括号、括号中的参数和冒号:,然后在缩进块中编写函数体,函数的返回值用return语句返回;
訾博ZiBo
2025/01/06
460
【Python】002-Python函数
【AICAMP —— Python】入门系列!(3. Python函数编程)
Python与其它编程语言一样,可以直接调用我们写好的函数,或者已经实现的函数。如我们可以使用系统自带的函数,求一个数的绝对值,使用abs函数,对其传入参数,得到输出。
灿视学长
2021/05/28
5190
Python学习笔记(二)·函数
当代码出现有规律的重复的时候,你就需要当心了,每次写3.14 * x * x不仅很麻烦,而且,如果要把3.14改成3.14159265359的时候,得全部替换。
公爵
2022/09/28
1.7K0
Python学习笔记(二)·函数
相关推荐
python基础----函数参数
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验