在Python中,可变参数的传递使用*args**kwargs来实现,其中:

  • *args表示任意个位置参数(positional argument),被表示为一个只读的数组(tuple);
  • **kwargs表示任意个关键字参数(keyword argument),被表示为一个字典(dict)。

例如:

>>> def foo(*args, **kwargs):
... print("*args:\t\t", args)
... print("**kwargs:\t", kwargs)
...
>>>
>>> foo()
*args: ()
**kwargs: {}
>>> foo(1)
*args: (1,)
**kwargs: {}
>>> foo(1, 2)
*args: (1, 2)
**kwargs: {}
>>>
>>> foo(a=1, b=2)
*args: ()
**kwargs: {'a': 1, 'b': 2}
>>>
>>> foo(1, 2, a=1, b=2, c=3)
*args: (1, 2)
**kwargs: {'a': 1, 'b': 2, 'c': 3}
>>>
>>> foo(1, 2, [3, 4, 5], a=1, b=2, c={'A':1, 'B':2, 'C':3})
*args: (1, 2, [3, 4, 5])
**kwargs: {'a': 1, 'b': 2, 'c': {'A': 1, 'B': 2, 'C': 3}}
>>>
>>> foo(1, a=1, 2, b=2, 3, c=3)
File "<stdin>", line 1
SyntaxError: positional argument follows keyword argument
>>>

注意: 位置参数(*args)必须在关键字参数(**kwargs)的前面。

另外,*args和**kwargs都是可以无限次地向下传递的(这一点类似Bash里的"$@"),例如:

  • foo_args.py
 #!/usr/bin/python

 from __future__ import print_function
import sys def l2_foo(*args):
print(">>L2:\t\t*args =", args, "\n") def l1_foo(head, *args):
print(" >L1: head =", head, "\t*args =", args)
l2_foo(*args) def main(argc, argv):
l1_foo(1)
l1_foo(1, 2)
l1_foo(1, 2, 3) return 0 if __name__ == '__main__':
argv = sys.argv
argc = len(argv)
sys.exit(main(argc, argv))

注意L6, L9 和 L11:

 6  def l2_foo(*args):
..
9 def l1_foo(head, *args):
..
11 l2_foo(*args)
  • 运行foo_args.py
$ ./foo_args.py
>L1: head = 1 *args = ()
>>L2: *args = () >L1: head = 1 *args = (2,)
>>L2: *args = (2,) >L1: head = 1 *args = (2, 3)
>>L2: *args = (2, 3)

最后,给出一个使用*args的更有工程意义的例子:

  • foo.py
 #!/usr/bin/python
from __future__ import print_function
import sys class Foo(object):
def __init__(self, name, oid):
self.name = name
self.oid = oid def get_name(self):
return self.name def set_name(self, name):
self.name = name def get_info(self):
return "name = %s, oid = %d" % (self.name, self.oid) def set_info(self, name, oid):
self.name = name
self.oid = oid class Bar(object):
def __init__(self, name, oid):
self.foo = Foo(name, oid) def __op_foo(self, method, *args):
func = getattr(self.foo, method)
try:
prop = func(*args)
return prop
except Exception as e:
print(e) def foo_set_name(self, name):
return self.__op_foo('set_name', name) def foo_get_name(self):
return self.__op_foo('get_name') def foo_set_info(self, name, oid):
return self.__op_foo('set_info', name, oid) def foo_get_info(self):
return self.__op_foo('get_info') def get_oid(self):
return self.foo.oid # XXX: Ugly but simple for demo def foo_arg0():
b = Bar('Jack', 12345)
s = b.foo_get_name()
print("foo_arg0: name = %s, oid = %d" % (s, b.get_oid())) def foo_arg1():
b = Bar('Jack', 12345)
o = b.foo_set_name('Lynn')
print("foo_arg1: return", o)
s = b.foo_get_name()
print("foo_arg1: name = %s, oid = %d" % (s, b.get_oid())) def foo_arg2():
b = Bar('Jack', 12345)
o = b.foo_set_info('Mary', 54321)
print("foo_arg2: return", o)
s = b.foo_get_info()
print("foo_arg2: %s" % s) def main(argc, argv):
if argc != 2:
sys.stderr.write("Usage: %s <func ID>\n" % argv[0])
return 1 func_id = int(argv[1])
exec('foo_arg%d()' % func_id) return 0 if __name__ == '__main__':
argv = sys.argv
argc = len(argv)
sys.exit(main(argc, argv))
  • 运行foo.py
$ ./foo.py
foo_arg0: name = Jack, oid =
$ ./foo.py
foo_arg1: return None
foo_arg1: name = Lynn, oid =
$ ./foo.py
foo_arg2: return None
foo_arg2: name = Mary, oid =

小结:在函数的参数列表中,零个*表示普通的位置参数, 一个*表示元组(tuple), 两个*表示字典(dict)。

 '*' * 0:   arg : regular arg
'*' * 1: *args: tuple (i.e. readonly list)
'*' * 2: **args: dict

[Python学习笔记-004] 可变参数*args和**kwargs的更多相关文章

  1. Python函数可变参数*args及**kwargs详解

    初学Python的同学们看到代码中类似func(*args, **kwargs)这样的函数参数定义时,经常感到一头雾水. 下面通过一个简单的例子来详细解释下Python函数可变参数*args及**kw ...

  2. Python可变参数*args和**kwargs

    本文我们将通过示例了解 Python函数的可变参数*args和 **kwargs的用法. 知识预备:Python 函数和 Python 函数参数 在Python编程中,我们定义一个函数来生成执行类似操 ...

  3. 理解 Python 中的可变参数 *args 和 **kwargs:

    默认参数:  Python是支持可变参数的,最简单的方法莫过于使用默认参数,例如: def getSum(x,y=5): print "x:", x print "y:& ...

  4. python函数可变参数*args和**kwargs区别

    #*args(元组列表)和**kwargs(字典)的区别 def tuple_test(*args): for i in args: print 'hello'+i s=('xuexi','mili' ...

  5. python学习笔记:函数参数

    1. 位置参数:一般的参数 2. 默认参数: def power(x, n=2): s = 1 while n > 0: n = n - 1 s = s * x return s 参数里有默认赋 ...

  6. Python学习笔记之默认参数

    函数定义时 参数定义的顺序必须是:必选参数.默认参数.可变参数和关键字参数. def test(a,b,c=1,*d,**e) pass

  7. 跟着太白老师学python 10day 函数的动态参数 *args, **kwargs, 形参的位置顺序

    1. *args 接收实参的位置参数, **kwargs接收实参的关键字参数 def func(*args, **kwargs): print(args, kwargs) func(1, 2, 3, ...

  8. python学习笔记-os模块参数

    python的os 模块提供了非常丰富的方法用来处理文件和目录.常用的方法如下表所示: os.access(path, mode) 检验权限模式 os.chdir(path) 改变当前工作目录 os. ...

  9. Python学习笔记004

    变量 变量的命名规则1. 要具有描述性2. 变量名只能_,数字,字母组成,不可以是空格或特殊字符(#?<.,¥$*!~)3. 不能以中文为变量名4. 不能以数字开头,下划线或者小写字母开头,驼峰 ...

随机推荐

  1. Java案例:超市库存管理系统

    案例介绍: 模拟真实的库存管理逻辑,完成超市管理系统的日常功能实现,见下图 案例需求分析: 根据案例介绍,我们进行分析,首先需要一个功能菜单,然后输入功能序号后,调用序号对应的功能方法,实现想要的操作 ...

  2. Android SimpleAdapter ViewBinder

  3. listview 嵌套checkbox响应item点击和button点击事件

    参考文档 http://www.eoeandroid.com/forum.php?mod=viewthread&tid=182280 一.主要要点 1. CheckBox的优先级比item高. ...

  4. Hdu1054 Strategic Game(最小覆盖点集)

    Strategic Game Problem Description Bob enjoys playing computer games, especially strategic games, bu ...

  5. flume遇到的问题

    Caused by: java.lang.IllegalStateException: Unable to add FlumeEventPointer [fileID=, offset=]. Queu ...

  6. 查找对端mac地址

    1.ping对端mac: 2.arp命令查找:

  7. DFS遍历中forward、backward以及cross边的界定

    再来看以下具体例子:

  8. Windows远程桌面连接ubuntu 16

    一.安装Xrdp Windows远程桌面使用的是RDP协议,所以ubuntu上就要先安装Xrdp,在ubuntu软件中心搜索xrdp安装. 安装xrdp的同时会自动安装vnc4server,xbase ...

  9. 数据库操作类《SqlHelper》

    一.背景 在看了一本书叫<Visual Studio 2010(C#)Windows数据库项目开发>后,觉得很多编程技术需要积累,因为一个简单的项目里包含的技术太多了,容易忘记.每次需要用 ...

  10. windform 重绘Treeview "+-"号图标

    模仿wind系统界面,重绘Treeview + - 号图标 一,首先需要图片 ,用于替换原有的 +-号 二.新建Tree扩展类 TreeViewEx继承TreeView using System; u ...