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()函数的源码

python中的 * 和 ** 作用含义的更多相关文章

  1. 关于Python中迭代器的作用

    迭代器的定义:含有__iter__()方法和__next__()方法的就是迭代器,即(iterate) 含有__iter__()方法就可以使用for循环,即iterable(可迭代的) Iterabl ...

  2. Python中__new__的作用

    __new__ 的作用 依照Python官方文档的说法,__new__方法主要是当你继承一些不可变的class时(比如int, str, tuple), 提供给你一个自定义这些类的实例化过程的途径.还 ...

  3. [问与答]Python 中 __all__ 的作用 ?

    你要是看Python的源码或者相关框架的源码,总是在 __init__.py 或者是源文件的开头看到一个 __all__ 变量的定义,今天就说说它的作用. orangleliu 问题出处 Can so ...

  4. Python 中 __all__ 的作用(转)

    之前看代码每次遇到import *时就会特别蒙,看到这篇文章一下子就弄明白了,原文地址:https://www.cnblogs.com/alamZ/p/6943869.html 1.测试文件foo.p ...

  5. Python中assert的作用?

    1. assert 的作用是什么? assert这个关键字我们称之为“断言”,当这个关键字后边的条件为假的时候,程序自动崩溃并抛出AssertionError的异常. 什么情况下我们会需要这样的代码呢 ...

  6. 简述python中的@staticmethod作用及用法

    关于@staticmethod,这里抛开修饰器的概念不谈,只简单谈它的作用和用法. staticmethod用于修饰类中的方法,使其可以在不创建类实例的情况下调用方法,这样做的好处是执行效率比较高.当 ...

  7. python中reload(sys)作用

    python在安装时,默认的编码是ascii,当程序中出现非ascii编码时,python的处理常常会报错UnicodeDecodeError: 'ascii' codec can't decode ...

  8. Python中*和**的作用(课堂小结)

    以前自学没注意过参数的传导中*和**的用法,这次趁着上课了解了一下,顺便写个随笔记一下. 1.打包用法 在参数传导中*args是不定长参数,传入的参数是不限制个数的,比如 def bdc(*args) ...

  9. 笔记-Python中逗号的作用

    1.用,去掉额外的换行符

随机推荐

  1. 使用let实现循环小例子

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  2. ArrayPool 源码解读之 byte[] 也能池化?

    一:背景 1. 讲故事 最近在分析一个 dump 的过程中发现其在 gen2 和 LOH 上有不少size较大的free,仔细看了下,这些free生前大多都是模板引擎生成的html片段的byte[]数 ...

  3. shell循环语句for

    1.方式1 for i in {list[0]} {list[1]} .. do 执行命令 done 2.方式2(三要素循环) for (( 初始值; 判断值; 步长; )) do 执行命令 done

  4. epoll经典代码示例

    1. epoll原理 原理性的知识不再另做说明,我在这里附上收藏整理的两篇经典文章: select与epoll的本质关系. select.poll.epoll之间的区别. 2. epoll服务器端经典 ...

  5. 内核软中断之tasklet机制

    1. 软中断IRQ简介 软中断(SoftIRQ)是内核提供的一种基于中断的延时机制, Linux内核定义的软中断有以下几种: enum { HI_SOFTIRQ=0, /*高优先级的tasklet*/ ...

  6. Fastjson反序列化漏洞基础

    Fastjson反序列化漏洞基础 FastJson是alibaba的一款开源JSON解析库,可用于将Java对象转换为其JSON表示形式,也可以用于将JSON字符串转换为等效的Java对象. 0x0 ...

  7. (7)java Spring Cloud+Spring boot+mybatis企业快速开发架构之SpringCloud-Spring Boot Starter的介绍及使用

    ​ Spring Boot 的便利性体现在,它简化了很多烦琐的配置,这对于开发人员来说是一个福音,通过引入各种 Spring Boot Starter 包可以快速搭建出一个项目的脚手架推荐分布式架构源 ...

  8. Win8 iis 环境搭建

    http://www.cnblogs.com/Joans/archive/2012/07/16/2593828.html 系统:win8 环境:vs2012 一:安装IIS 比较win7的安装来说,多 ...

  9. Centos8.X 搭建Prometheus+node_exporter+Grafana实时监控平台

    Prometheus Promtheus是一个时间序列数据库,其采集的数据会以文件的形式存储在本地中,因此项目目录下需要一个data目录,需要我们自己创建,下面会讲到 下载 下载好的.tar.gz包放 ...

  10. 如何快速下载ubuntu镜像

    使用国内镜像地址下载: 中科大http://mirrors.ustc.edu.cn/ubuntu-releases/ 阿里云开源镜像站http://mirrors.aliyun.com/ubuntu- ...