简介
本节介绍可变参数函数参数,有时也称为 *args
和 **kwargs
。
This tutorial is from open-source community. Access the source code
💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版
本节介绍可变参数函数参数,有时也称为 *args
和 **kwargs
。
一个接受任意数量参数的函数被称为使用了可变参数。例如:
def f(x, *args):
...
函数调用:
f(1,2,3,4,5)
额外的参数会作为一个元组传递。
def f(x, *args):
## x -> 1
## args -> (2,3,4,5)
一个函数也可以接受任意数量的关键字参数。例如:
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' }
...
这个函数可以接受任意组合的位置参数或关键字参数。它有时用于编写包装器,或者当你想要将参数传递给另一个函数时使用。
元组可以展开为可变参数。
numbers = (2,3,4)
f(1, *numbers) ## 等同于 f(1,2,3,4)
字典也可以展开为关键字参数。
options = {
'color' : 'red',
'delimiter' : ',',
'width' : 400
}
f(data, **options)
## 等同于 f(data, color='red', delimiter=',', width=400)
尝试定义以下函数:
>>> 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
是如何收集所有额外参数的。
假设你从一个文件中读取了一些数据,并得到了一个这样的元组:
>>> 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: Stock.__init__() missing 2 required positional arguments:'shares' and 'price'
>>>
使用 *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)
>>>
在你的 report.py
程序中,你使用如下代码创建了一个实例列表:
def read_portfolio(filename):
'''
将股票投资组合文件读取为一个字典列表,字典包含键
name、shares 和 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)
来简化这段代码。进行这个更改。
fileparse.parse_csv()
函数有一些用于更改文件分隔符和错误报告的选项。也许你想将这些选项暴露给上面的 read_portfolio()
函数。进行如下更改:
def read_portfolio(filename, **opts):
'''
将股票投资组合文件读取为一个字典列表,字典包含键
name、shares 和 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('missing.csv')
第4行:无法转换 ['MSFT', '', '51.23']
第4行:原因是 int() 无法将空字符串转换为十进制整数
第7行:无法转换 ['IBM', '', '70.44']
第7行:原因是 int() 无法将空字符串转换为十进制整数
>>>
现在,尝试抑制错误:
>>> import report
>>> port = report.read_portfolio('missing.csv', silence_errors=True)
>>>
恭喜你!你已经完成了可变参数实验。你可以在 LabEx 中练习更多实验来提升你的技能。