翻译:《实用的Python编程》07_01_Variable_arguments
2021-03-20 09:49
826 查看
目录 | 上一节 (6.4 生成器表达式) | 下一节 (7.2 匿名函数)
7.1 可变参数
本节介绍可变(variadic)参数。有时,可变参数使用
*args和
**kwargs进行表示。
可变位置参数(*args
)
如果一个函数接受任意数量的(位置)参数,那么我们称该函数使用了可变参数(variable arguments)。示例:
def f(x, *args): ...
函数调用:
f(1,2,3,4,5)
额外的参数作为元组进行传递:
def f(x, *args): # x -> 1 # args -> (2,3,4,5)
可变关键字参数(**kwargs
)
一个函数也可以接受任意数量的关键字参数。示例:
def f(x, y, **kwargs): ...
函数调用:
f(2, 3, flag=True, mode='fast', header='debug')
额外的参数作为字典进行传递:
def f(x, y, **kwargs): # x -> 2 # y -> 3 # kwargs -> { 'flag': True, 'mode': 'fast', 'header': 'debug' }
可变位置参数与可变关键字参数结合使用
一个函数可以同时接受可变非关键字参数和可变关键字参数。
def f(*args, **kwargs): ...
函数调用:
f(2, 3, flag=True, mode='fast', header='debug')
这些参数被分为位置参数和关键字参数两部分。
def f(*args, **kwargs): # args = (2, 3) # kwargs -> { 'flag': True, 'mode': 'fast', 'header': 'debug' } ...
上述函数接受任意数量的位置参数和关键字参数。当编写包装器(wrappers)或要将参数传递给另一个函数时使用。
传递元组和字典
元组可扩展为可变参数:
numbers = (2,3,4) f(1, *numbers) # Same as f(1,2,3,4)
字典也可以扩展为关键字参数:
options = { 'color' : 'red', 'delimiter' : ',', 'width' : 400 } f(data, **options) # Same as f(data, color='red', delimiter=',', width=400)
练习
练习 7.1: 可变参数的简单示例
尝试定义下列函数:
>>> def avg(x,*more): return float(x+sum(more))/(1+len(more)) >>> avg(10,11) 10.5 >>> avg(3,4,5) 4.0 >>> avg(1,2,3,4,5,6) 3.5 >>>
请注意
*more是如何收集其它所有参数的。
练习 7.2:将元组和字典作为参数进行传递
假设你从文件中读取数据,并获得一个元组。例如:
>>> data = ('GOOG', 100, 490.1) >>>
现在,假设你想根据上面的数据创建一个
Stock对象。如果你直接传
data,那就行不通了:
>>> from stock import Stock >>> s = Stock(data) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: __init__() takes exactly 4 arguments (2 given) >>>
这个问题很容易解决,直接使用
*data即可。试试看:
>>> s = Stock(*data) >>> s Stock('GOOG', 100, 490.1) >>>
如果你拥有的是一个字典,那么你可以改用
**。示例:
>>> data = { 'name': 'GOOG', 'shares': 100, 'price': 490.1 } >>> s = Stock(**data) Stock('GOOG', 100, 490.1) >>>
练习 7.3:创建实例列表
在
report.py程序中,我们使用如下代码创建了一个实例列表:
def read_portfolio(filename): ''' Read a stock portfolio file into a list of dictionaries with keys name, shares, and price. ''' with open(filename) as lines: portdicts = fileparse.parse_csv(lines, select=['name','shares','price'], types=[str,int,float]) portfolio = [ Stock(d['name'], d['shares'], d['price']) for d in portdicts ] return Portfolio(portfolio)
我们可以改用
Stock(**d)来简化代码。请完成修改。
练习 7.4:参数传递
fileparse.parse_csv()函数具有一些选项,用于更改文件分隔符和错误报告。也许你会想把这些选择暴露给上面的
read_portfolio()函数。请完成修改:
def read_portfolio(filename, **opts): ''' Read a stock portfolio file into a list of dictionaries with keys name, shares, and price. ''' with open(filename) as lines: portdicts = fileparse.parse_csv(lines, select=['name','shares','price'], types=[str,int,float], **opts) portfolio = [ Stock(**d) for d in portdicts ] return Portfolio(portfolio)
修改完成后,尝试阅读读取一些带有错误的文件:
>>> import report >>> port = report.read_portfolio('Data/missing.csv') Row 4: Couldn't convert ['MSFT', '', '51.23'] Row 4: Reason invalid literal for int() with base 10: '' Row 7: Couldn't convert ['IBM', '', '70.44'] Row 7: Reason invalid literal for int() with base 10: '' >>>
现在,尝试隐藏错误:
>>> import report >>> port = report.read_portfolio('Data/missing.csv', silence_errors=True) >>>
目录 | 上一节 (6.4 生成器表达式) | 下一节 (7.2 匿名函数)
相关文章推荐
- 翻译:《实用的Python编程》03_01_Script
- 翻译:《实用的Python编程》01_00_Overview
- [翻译] Macros with a Variable Number of Arguments - GCC
- 翻译:《实用的Python编程》01_06_Files
- 07-01 Java 封装
- 可变参数宏的一种实现:(Macros with a Variable Number of Arguments)
- 【unity3D】【siki的坦克大战】 【学习记录(一)】 【01-07】
- PHP学习散记 2012_01_07(MySQL)
- 【C#基础】【语法01】课堂作业题 01-07
- three.js 07-01 之 Sprite 粒子系统
- 文章翻译——使用 GNU 的 GDB调试器,内存布局和栈——01
- kb-07专题--线段树-01-单点修改,区间查和
- 增值翻译系列谈(01)——概念界定和辨析
- MyBatis 学习记录01--07/01
- 实验作品集:coverflow alpha 0.3(2011 07 01)
- Aug-07-01
- [iOS翻译]《The Swift Programming Language》系列:Welcome to Swift-01
- [iOS翻译]《The Swift Programming Language》系列:Welcome to Swift-01
- 翻译:《实用的Python编程》03_02_More_functions
- [翻译]架构师应该知道的97件事_01客户需求重于个人简历