关于python:翻译实用的Python编程0701Variablearguments

33次阅读

共计 2778 个字符,预计需要花费 7 分钟才能阅读完成。

目录 | 上一节 (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 匿名函数)]()

注:残缺翻译见 https://github.com/codists/practical-python-zh

正文完
 0