理解python中的'*','*args','**','**kwargs'
本文来源:http://blog.csdn.net/callinglove/article/details/45483097
让我们通过以下6步来理解:
1. 通过一个函数调用来理解’*’的作用
2. 通过一个函数的定义来理解’*args’的含义
3. 通过一个函数的调用来理解’**’的作用
4. 通过一个函数的定义来解’**kwargs’的含义
5.注意点:参数arg、*args、**kwargs三个参数的位置必须是一定的。必须是(arg,*args,**kwargs)这个顺序,否则程序会报错。
6. 通过一个应用实例来说明’args’,’kwargs’应用场景以及为何要使用它
1、通过一个函数调用来理解’*’的作用
def fun(a,b,c):
print(a,b,c)
fun(1,2,3) #1 2 3
l=[1,2,3]
fun(*l) #1 2 3
l=(1,2,3)
fun(*l) #1 2 3 元组也可以
l=[1,2,3,4]
fun(*l) #TypeError: fun() takes 3 positional arguments but 4 were given
‘*’ 做了什么?
它拆开数列’l’的数值作为位置参数,并吧这些位置参数传给函数’fun’来调用。
因此拆数列、传位置参数意味着fun(*l)与fun(1,2,3)是等效的,因为l = [1,2,3]
数列’l’含有四个数值.因此,我们试图调用’fun(*l)’,’l’中数值拆开传给函数fun作为位置参数。
但是,’l’中有四个数值,调用’fun(*l)’相当于调用’fun(3,6,9,1)’,又因为函数’fun’定义中只用三个位置参数,因此我们得到这个错误。
2、通过一个函数的定义来理解’*args’的含义
def fun(*args):
print(args,type(args))
fun(10) #(10,) <class 'tuple'>
fun(10,20) #(10,20) <class 'tuple'>
fun([1,2],20,[2,3]) #([1, 2],) <class 'tuple'>
#代码2
def fun(x,y,*args):
print(x,y,args)
fun(1,2,3,4,5) #1 2 (3, 4, 5)
#代码3
def fun(x,y,*args,z):
print(x,y,args,z)
fun(1,2,3,4,5) #TypeError: fun() missing 1 required keyword-only argument: 'z'
可见:1、*args 用来将参数打包成tuple给函数体调用,参数个数不受限制,*args接收元组作为位置参数。
2、由代码2知:x为1,y为2,即第一个和第二个位置参数,之后只有一个参数*args,因此,*args接收除第一个和第二个参数之外的参数作为元组,即(3,4,5)。
3、由代码3知:位置参数z不能放置在*args之后
3、通过一个函数的调用来理解’**’的作用
def fun(a,b,c):
print(a,b,c)
fun(1,2,3) #1 2 3
fun(a=1,b=2,c=3) #1 2 3
d={'b':2,'c':3}
fun(1,**d) #1 2 3
dict={'b':2,'c':3}
fun(1,**dict) #1 2 3
d={'a':1,'b':2,'c':3,'d':4}
fun(**d) #TypeError: fun() got an unexpected keyword argument 'd'
d={'a':1,'b':2,'d':4}
fun(**d) #TypeError: fun() got an unexpected keyword argument 'd'
在函数调用中使用”*”,我们需要元组;在函数调用中使用”**”,我们需要一个字典,字典中参数个数不能多,也不能少。
4、通过函数定义来理解’**kwargs’的含义
def fun(a,**kwargs):
print(a,kwargs)
fun(1,b=2,c=3) #1 {'b': 2, 'c': 3}
fun(1,**{'b':2,'c':3}) #1 {'b': 2, 'c': 3}
fun(1,{'b':2,'c':3}) #TypeError: fun() takes 1 positional argument but 2 were given
在函数定义中”**kwargs”意味着什么?
用”**kwargs”定义函数,kwargs接收除常规参数列表之外的键值参数字典,参数个数不固定,kwargs是个字典。
可以多传参数吗?因为参数不固定,所以也就没有多少的概念了。
5、注意点:参数arg、*args、**kwargs三个参数的位置必须是一定的。必须是(arg,*args,**kwargs)这个顺序,否则程序会报错。
6、通过一个应用实例来说明’args’,’kwargs’应用场景以及为何要使用它
class Model:
def __init__(self,name):
self.name=name
def save(self,force_update=False,force_insert=False):
if force_update and force_insert:
raise ValueError('cannt perform both operations') #故意写作cannt而非cannot
if force_update:
print('updated an existing record')
if force_insert:
print('created a new record') class Child(Model):
def save(self,*args,**kwargs):
if self.name=='abcd':
super().save(*args,**kwargs)
#super(Model,self).save(*args,**kwargs)
else:
return None
child=Child('abcd')
child.save(force_update=True)
child.save(force_insert=True)
child.save(force_insert=True,force_update=True)
# updated an existing record
# created a new record
# ValueError: cannt perform both operations
实际上对应的保存动作发生在’Model’的’save’方法中。所以我们调用子类的的’save()’方法而非’Model’的方法.子类Child的’save()’接收任何父类save()需要的参数,并传给父类方法。因此,子类’save()’方法参数列表中有”*args”和”**kwargs”,它们可以接收任意位置参数或键值参数,常规参数列表除外。
理解python中的'*','*args','**','**kwargs'的更多相关文章
- 理解理解python中的'*','*args','**','**kwargs'
http://blog.csdn.net/callinglove/article/details/45483097 讲了一大堆, 我也是用来理解类继承当中的参数行为的. =============== ...
- 理解 Python 中的 *args 和 **kwargs
Python是支持可变参数的,最简单的方法莫过于使用默认参数,例如: def test_defargs(one, two = 2): print 'Required argument: ', one ...
- python 中参数*args, **kwargs
def func(*args, **kwargs): print 'args : ', args print 'kwargs :', kwargs def test(): func(1,2,'x',' ...
- 理解 Python 中的可变参数 *args 和 **kwargs:
默认参数: Python是支持可变参数的,最简单的方法莫过于使用默认参数,例如: def getSum(x,y=5): print "x:", x print "y:& ...
- [转]深刻理解Python中的元类(metaclass)以及元类实现单例模式
使用元类 深刻理解Python中的元类(metaclass)以及元类实现单例模式 在看一些框架源代码的过程中碰到很多元类的实例,看起来很吃力很晦涩:在看python cookbook中关于元类创建单例 ...
- python可变参数*args, **kwargs
python可变参数*args, **kwargs def foo(* args, ** kwargs): print ' args = ', args print ' kwargs = ', k ...
- 【转】你真的理解Python中MRO算法吗?
你真的理解Python中MRO算法吗? MRO(Method Resolution Order):方法解析顺序. Python语言包含了很多优秀的特性,其中多重继承就是其中之一,但是多重继承会引发很多 ...
- 深入理解Python中的yield和send
send方法和next方法唯一的区别是在执行send方法会首先把上一次挂起的yield语句的返回值通过参数设定,从而实现与生成器方法的交互. 但是需要注意,在一个生成器对象没有执行next方法之前,由 ...
- 如何理解python中的if __name__=='main'的作用
一. 一个浅显易懂的比喻 我们在学习python编程时,不可避免的会遇到if __name__=='main'这样的语句,它到底有什么作用呢? <如何简单地理解Python中的if __name ...
随机推荐
- 第1节 HUE:13、hue的下载以及安装配置
hue的基本介绍:主要是用于与其他各个框架做整合的,提供一个web界面可以供我们去操作其他的大数据框架可以理解为这个hue就是一个与其他各个框架整合的工具,hue本身不提供任何的功能,所有的功能,都是 ...
- '/'和‘/*’差异造成的No mapping found for HTTP request with URI [/springMVC/welcome.jsp] in DispatcherServlet with name 'springmvc'
在采用springMVC框架的时候所遇到的一个小问题,其中web.xml中关于servlet的配置如下: <servlet> <servlet-name>springmvc&l ...
- KMP【模板】 && 洛谷 P3375
题目传送门 解题思路: 首先说KMP的作用:对于两个字符串A,B(A.size() > B.size()),求B是否是A的一个字串或B在A里的位置或A里有几个B,说白了就是字符串匹配. 下面创设 ...
- java#StringBuffer&StringBuilder
StringBuffer A thread-safe, mutable sequence of characters. A string buffer is like a String, but ca ...
- [Luogu][P2458] [SDOI2006]保安站岗
题目链接 看起来似乎跟最小点覆盖有点像.但区别在于: 最小点覆盖要求所有边在其中,而本题要求所有点在其中. 即:一个点不选时,它的儿子不一定需要全选. 画图理解: 对于这样一幅图,本题中可以这样选择: ...
- 计算机是如何计算的、运行时栈帧分析(神奇i++续)
关于i++的疑问 通过JVM javap -c 查看字节码执行步骤了解了i++之后,衍生了一个问题: int num1=50; num1++*2执行的是imul(将栈顶两int类型数相乘,结果入栈), ...
- JavaScript基于原型的继承
在一个纯粹的原型模式中,我们会摒弃类,转而专注于对象,基于原型的继承相比基于类的继承的概念上更为简单 if( typeof Object.beget !== 'function') { Object. ...
- NIO 聊天室代码实现
服务器端 package com.ronnie.nio.groupChat; import java.io.IOException; import java.net.InetSocketAddress ...
- spark源码单步跟踪阅读-从毛片说起
想当年读大学时,那时毛片还叫毛片,现在有文明的叫法了,叫小电影或者爱情动作片.那时宿舍有位大神,喜欢看各种毛片,当我们纠结于毛片上的马赛克时,大神大手一挥说道:这算啥,阅尽天下毛片,心中自然无码!突然 ...
- Java中用单例模式有什么好处?
Java Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在. 使用Singleton的好处还在于可以节省内存,因为它限制了实例的个数,有利于Java垃圾回收( ...