位置で渡すか、名前で渡すか
引数は位置(パラメータに順番に対応)でも、名前(quantity=200)でも渡せます。同じ型の入力がいくつもある関数では、名前を付けると呼び出しが読みやすくなり、順番も自由になります。位置引数は先に書き、名前を1つ使ったら、残りも名前付きにします。
def pnl(entry, exit_price, quantity):
return (exit_price - entry) * quantity
print(pnl(184.0, 185.5, 200)) # 300.0
print(pnl(quantity=200, entry=184.0, exit_price=185.5)) # 300.0デフォルト値でパラメータを省略可能にする
def の行に name=value と書くと、呼び出し側はその引数を省略でき、デフォルト値が使われます。デフォルト値のあるパラメータは、ないものの後ろに置きます。手数料率や下限のように「たいてい同じ」設定に向いていて、名前を指定すればいつでも上書きできます。
# Parameters with a default are optional
def fee(notional, rate=0.001, minimum=1.0):
return max(minimum, notional * rate)
print(fee(36850.0)) # 36.85
print(fee(36850.0, rate=0.0005)) # 18.425
print(fee(100.0, minimum=0.5)) # 0.5任意の個数の引数:*args
*prices と書いたパラメータは、余った位置引数をすべてタプルに集めるので、average(1, 2, 3) でも average(1, 2, 3, 4, 5) でも動きます。呼び出し側では逆のこともでき、average(*quotes) はリストを個別の引数に展開します。
# *prices collects the extra arguments into a tuple
def average(*prices):
return sum(prices) / len(prices)
print(average(184.0, 185.0, 186.0)) # 185.0
quotes = [184.0, 185.0]
print(average(*quotes)) # 184.5任意の名前付きオプション:**options
同様に **options は、余った名前付き引数を、名前と値の辞書にまとめます(辞書はまもなく独立したトピックで扱います)。注文の設定のような、省略可能な追加項目を受け取る関数に向いています。sorted(options) は名前をアルファベット順に返すので、出力が予測しやすくなります。
# **options collects extra named arguments into a dictionary
def describe(symbol, **options):
text = symbol
for name in sorted(options):
text += f" {name}={options[name]}"
return text
print(describe("AAPL", tif="day", limit=184.5)) # AAPL limit=184.5 tif=dayミュータブルなデフォルト値の落とし穴
デフォルト値は、呼び出しのたびではなく、関数が定義されるときに1回だけ作られます。数値や文字列なら問題ありません。しかしリストでは、デフォルトを使うすべての呼び出しが同じリストを共有して変更してしまいます。定番の対策は、デフォルトを None にして、関数の中で新しいリストを作ることです。
# A default list is created once and shared by every call
def add_fill(fill, fills=[]):
fills.append(fill)
return fills
print(add_fill(100)) # [100]
print(add_fill(200)) # [100, 200] <- surprise: the same list
# The fix: default to None and build a new list inside
def add_fill_fixed(fill, fills=None):
if fills is None:
fills = []
fills.append(fill)
return fills
print(add_fill_fixed(100)) # [100]
print(add_fill_fixed(200)) # [200]呼び出しと定義をそろえるパラメータにデフォルト値を付けると、短い呼び出しの意味が変わります。黙って適用されても困らない値を選びましょう。呼び出し側が必ず決めるべき値は、デフォルトを付けないでおきます。そうすれば、Pythonは推測せずに不足している引数を報告してくれます。
- 同じ型の入力が複数あるときは、名前付きで呼び出す
- たいてい同じ設定にはデフォルト値を。リストや辞書は使わない
- 任意個数の値には
*args、名前付きの追加項目には**options
次はスコープとクロージャです。関数がどの名前を見られるのか、どうやって値を覚えておくのかを学びます。
ラボ:採点される内容
position_pnlで数量と売買の向きを省略可能にする25点averageで任意の個数の価格を受け取る25点describe_orderで名前付きの注文オプションを受け取る25点add_fillで共有リストの落とし穴を避ける25点