python中的 * 和 ** ,能够让函数支持任意数量的参数,它们在函数定义和调用中,有着不同的目的

一. 打包参数

* 的作用:在函数定义中,收集所有位置参数到一个新的元组,并将整个元组赋值给变量args

>>> def f(*args):      # * 在函数定义中使用
print(args) >>> f()
()
>>> f(1)
(1,)
>>> f(1, 2, 3, 4)
(1, 2, 3, 4)

** 的作用:在函数定义中,收集关键字参数到一个新的字典,并将整个字典赋值给变量kwargs

>>> def f(**kwargs):        # ** 在函数定义中使用
print(kwargs) >>> f()
{}
>>> f(a=1, b=2)
{'a': 1, 'b': 2}

二. 解包参数

* 的作用:在函数调用中,* 能够将元组或列表解包成不同的参数

>>> def func(a, b, c, d):
print(a, b, c, d) >>> args = (1, 2, 3, 4)
>>> func(*args) # * 在函数调用中使用
2 3 4 >>> args = [1, 2, 3, 4]
>>> func(*args)
2 3 4

** 的作用:在函数调用中,** 会以键/值的形式解包一个字典,使其成为一个独立的关键字参数

>>> def func(a, b, c, d):
print(a, b, c, d) >>> kwargs = {"a": 1, "b": 2, "c": 3, "d": 4}
>>> func(**kwargs) # ** 在函数调用中使用
2 3 4

三. 注意

1. 在函数定义时, * 表示打包,在函数体内部, * 表示的却是解包,事实上,下面例子中print(*args)是print()函数的调用

>>> def foo(*args, **kwargs):
print(args) #未解包参数
print(*args) #解包参数 >>> v = (1, 2, 4)
>>> d = {'a':1, 'b':12}
>>> foo(v, d)
((1, 2, 4), {'a': 1, 'b': 12})
(1, 2, 4) {'a': 1, 'b': 12}

2. * 和 ** 的打包和解包并不能脱离函数而存在

如下的例子中,表面上看没有调用什么函数,实际上调用了format()函数

>>> c = {"name": 'zhang', "age": 2}
>>> **c
SyntaxError: invalid syntax
>>>
>>> "Name:{name}, Age:{age}".format(**c)
'Name:zhang, Age:2'

参考源码中对format函数的定义

 

这里为什么不用print()函数而用format()呢

可以试试print()函数来解包

>>> print(**c)
Traceback (most recent call last):
File "<pyshell#40>", line 1, in <module>
print(**c)
TypeError: 'age' is an invalid keyword argument for this function

因为print()函数只支持 *args,不支持 **kwargs,源码附上

 

四. 在ddt中的应用

已知接口自动化中all_caseDatas是有N个字典组成的列表,@ddt.data(*all_caseDatas)中,data()是一个函数,调用函数时,参数*all_caseDatas自动将列表[{...}, {...}, {...}...]解包为{...}, {...}, {...}...,再传递给测试用例函数test_my_request(),这就是@ddt.data将每一条数据作为一条测试用例的原理

@ddt.data(*all_caseDatas)
def test_my_request(self, case_data):
global global_var
if len(global_var) != 0 and case_data["request_data"] is not None:
for key, value in global_var.items():
if case_data["request_data"].find(key) != -1:
case_data["request_data"] = case_data["request_data"].replace(key, value)

ddt中data()函数的源码

最新文章

  1. 『TCP/IP详解——卷一:协议』读书笔记——13
  2. Java中常用的内存区域
  3. bzoj 2761 平衡树
  4. Android系统的体系结构、开发语言及源码结构
  5. Android开发学习之Adapter
  6. Tinyxml 操作XML
  7. 模拟jquery封装选择器
  8. Sql Server相关的性能计数器
  9. sql 事务日志传输
  10. plsql 数据迁移——导出表结构,表数据,表序号
  11. uploadify Cookie 验证登入上传问题
  12. python:3种爬虫的优缺点
  13. Python3.6.2在线安装pymysql模块
  14. leetcode41
  15. 安卓4.2用adb 获取屏幕分辨率等信息
  16. 性能优化:使用SparseArray代替HashMap&lt;Integer,Object&gt;(转)
  17. jQuery 核心 - noConflict() 方法
  18. 总是有个yumBackend.py阻止我用yum进行更新
  19. 【知识笔记】ASP.NET报错问题
  20. zabbix 安装错误汇总

热门文章

  1. validity属性返回对象中的属性值
  2. Metasploit用法详解
  3. Pycharm去除波浪线等相关操作
  4. 针对Autocad 2014 第二次安装不上的问题
  5. Identity角色管理四(删除角色)
  6. Abp VNext权限定义
  7. https://www.cnblogs.com/spec-dog/p/11161744.html
  8. wpf 多表头
  9. 深度学习——前向传播算法和反向传播算法(BP算法)及其推导
  10. Composer基础