在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. spoj COT2(树上莫队)

    模板.树上莫队的分块就是按dfn分,然后区间之间转移时注意一下就好.有个图方便理解http://blog.csdn.net/thy_asdf/article/details/47377709: #in ...

  2. android Activity中设置setResult 没有触发onActivityResult

    昨天修改<manifest 文件中activity 的 模式为单例模式:android:launchMode="singleTask" ,发现我的onActivityResu ...

  3. python_运算符与表达式

    运算符与表达式 python运算符 运算符 功能说明 + 算术加法,列表.元组.字符串合并与连接,正号 - 算术减法,集合差集,相反数 * 算术乘法,序列重复 / 真除法 // 求整商,但如果操作数中 ...

  4. SRM475

    250pt: 题意:有最长N=17的一条格子,每个格子是W.B和R三种颜色之一,当某个格子上有兔子时,下一个回合该兔子按照以下的规则移动: 如果兔子在第一个格子,则向右移动一格: 否则如果兔子在倒数两 ...

  5. 使用命令行打包 nuget 包

    对于那些不打算涉及这么复杂而又想制作自己的 nuget 包的园友们,我是推荐使用 Nuget Package Explorer 来制作的.关于这个图形化的 nuget 包管理软件的使用,博客园内有相关 ...

  6. 完美融合 nextjs 和 antd

    相信大家在使用nextjs的时候,难免遇到一些坑.其实可能大部分原因在于 nextjs 做了很多封装,我们可能不能第一时间搞清楚包括它相关的所有配置,比如其中的webpack配置.我前面也写过 SSR ...

  7. 受邀与微软售前技术团队参与TFS技术沟通会议

    微软正式发布Azure DevOps Server 2019的第一个版本,作为Team Foundation Server (TFS)2018的升级版本和替代产品. 作为开发运维一体化平台的主打产品, ...

  8. python- 动态加载目录下所有的类

    # 背景 自动化测试框架中model层下有很多类,用来操作mysql的,使用的时候需要把全部的类加载进来,需要使用到动态加载类 # 解决方法 使用pkgutil,内置的方法,常用的话有两个方法 ite ...

  9. .NET MVC 学习笔记(五)— Data Validation

    .NET MVC 学习笔记(五)—— Data Validation 在实际应用中,我们需要对数据进行增查改删业务,在添加和修改过程中,无论你编写什么样的网页程序,都需要对用户的数据进行验证,以确数据 ...

  10. JSON Web Token in ASP.NET Web API 2 using Owin

    In the previous post Decouple OWIN Authorization Server from Resource Server we saw how we can separ ...