在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相关工具下载、配置环境变量

    相关工具下载 JDK:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html Eclip ...

  2. Maven的依赖管理

    我们知道dependencies是可以被继承的,这个时候我们就想到让我们的发生了共用的依赖元素转移到parent中,这样我们又进一步的优化了配置.可是问题也随之而来,如果有一天我创建了一个新的模块,但 ...

  3. find的用法(完整)

    一.根据文件或者正则表达式进行匹配 1.列出当前目录(/.code)及子目录下所有文件和文件夹 find . 2.在当前目录(/.code)下查找以.pdf结尾的文件名 find .  -name & ...

  4. Android-Kotlin-枚举enum

    案例一 星期: 星期的枚举:enum class 类名 {} package cn.kotlin.kotlin_oop09 /** * 定义星期的枚举类 */ enum class MyEnumera ...

  5. Android-Java-引用数据类型参数传递内存图

    首先看一个案例: package android.java.oop04; class Person { public String name; public void showName() { Sys ...

  6. spring mvc 的请求流程

    SpringMVC核心处理流程: 1.DispatcherServlet前端控制器接收发过来的请求,交给HandlerMapping处理器映射器 2.HandlerMapping处理器映射器,根据请求 ...

  7. Spring下配置几种常用连接池

    1.连接池概述 数据库连接是一种关键的有限的昂贵的资源,这一点在多用户的网页应用程序中体现得尤为突出.对数据库连接的管理能显著影响到整个应用程序的伸缩性和健壮性,影响到程序的性能指标.数据库连接池正是 ...

  8. C语言Socket-模拟远程CMD(客户端向服务器发送命令,服务器执行该命令)

    服务端(server) #include <stdio.h> #include <winsock2.h> #pragma comment(lib,"ws2_32.li ...

  9. 模拟ssh、黏包、hashlib模块

    一.模拟ssh 1.subprocess模块 ipconfig -all dir subprocess模块是python从2.4版本开始引入的模块.主要用来取代 一些旧的模块方法,如os.system ...

  10. Java - 阅读与查找

    WebSites http://www.importnew.com/ https://www.java-tips.org/ http://www.javaworld.com/ http://www.p ...