原文:『実用的なPythonプログラミング』07_01_Variable_arguments
5811 ワード
目次|前節(6.4ジェネレータ式)|[次節(7.2匿名関数)]()
7.1可変パラメータ
このセクションでは、可変(variadic)パラメータについて説明します.可変パラメータは、
可変位置パラメータ(
1つの関数が任意の数の(位置)パラメータを受け入れる場合,この関数は可変パラメータ(variable arguments)を用いたと呼ぶ.例:
関数呼び出し:
追加のパラメータをタプルとして渡します.
可変キーワードパラメータ(
1つの関数は、任意の数のキーワードパラメータを受け入れることもできます.例:
関数呼び出し:
追加のパラメータを辞書として渡します.
可変位置パラメータと可変キーワードパラメータを組み合わせて使用
1つの関数は、可変非キーワードパラメータと可変キーワードパラメータを同時に受け入れることができます.
関数呼び出し:
これらのパラメータは、位置パラメータとキーワードパラメータの2つの部分に分けられます.
上記の関数は、任意の数の位置パラメータとキーワードパラメータを受け入れます.ラップ(wrappers)を作成したり、パラメータを別の関数に渡したりするときに使用します.
メタグループと辞書の転送
タプルは可変パラメータに拡張できます.
辞書はキーワードパラメータに拡張することもできます.
練習する
練習7.1:可変パラメータの簡単な例
次の関数を定義してみます.
練習7.2:メタグループと辞書をパラメータとして渡す
ファイルからデータを読み込み、メタグループを取得するとします.例:
次に、上記のデータに基づいて
この問題は簡単に解決できるので、
辞書を持っている場合は、
練習7.3:インスタンスリストの作成
練習7.4:パラメータ伝達
修正が完了したら、エラーのあるファイルを読み込みます.
エラーを非表示にしようとします.
目次|前節(6.4ジェネレータ式)|[次節(7.2匿名関数)]()
注:完全な翻訳はhttps://github.com/codists/practical-python-zhを参照
7.1可変パラメータ
このセクションでは、可変(variadic)パラメータについて説明します.可変パラメータは、
*args
および**kwargs
で表される場合がある.可変位置パラメータ(
*args
)1つの関数が任意の数の(位置)パラメータを受け入れる場合,この関数は可変パラメータ(variable arguments)を用いたと呼ぶ.例:
def f(x, *args):
...
関数呼び出し:
f(1,2,3,4,5)
追加のパラメータをタプルとして渡します.
def f(x, *args):
# x -> 1
# args -> (2,3,4,5)
可変キーワードパラメータ(
**kwargs
)1つの関数は、任意の数のキーワードパラメータを受け入れることもできます.例:
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' }
可変位置パラメータと可変キーワードパラメータを組み合わせて使用
1つの関数は、可変非キーワードパラメータと可変キーワードパラメータを同時に受け入れることができます.
def f(*args, **kwargs):
...
関数呼び出し:
f(2, 3, flag=True, mode='fast', header='debug')
これらのパラメータは、位置パラメータとキーワードパラメータの2つの部分に分けられます.
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 "", line 1, in
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を参照