Pythonでタイプヒントを使用してデフォルトのパラメーター値を追加する


236

このような機能がある場合:

def foo(name, opts={}):
  pass

パラメータに型ヒントを追加したいのですが、どうすればよいですか?私が想定した方法では、構文エラーが発生します。

def foo(name: str, opts={}: dict) -> str:
  pass

以下は構文エラーをスローしませんが、このケースを処理する直感的な方法のようには見えません。

def foo(name: str, opts: dict={}) -> str:
  pass

typingドキュメントやGoogle検索で何も見つかりません。

編集:デフォルトの引数がPythonでどのように機能するかは知りませんでしたが、この質問のために、上の例をそのまま使用します。一般に、次のことを行う方がはるかに適切です。

def foo(name: str, opts: dict=None) -> str:
  if not opts:
    opts={}
  pass

4
最後の関数は正しい方法です。scala言語も同じです。
イスラエルウンターマン16

14
問題につながる-あなたは、変更可能なデフォルトのタイプ持っている
noɥʇʎԀʎzɐɹƆ

私の更新の答え、@josh見る
noɥʇʎԀʎzɐɹƆ

@noɥʇʎԀʎzɐɹƆメモなどに使用している場合を除きます。:P
Mateen Ulhaq

回答:


281

あなたの2番目の方法は正しいです。

def foo(opts: dict = {}):
    pass

print(foo.__annotations__)

この出力

{'opts': <class 'dict'>}

PEP 484に記載されていないことは事実ですが、タイプヒントは関数注釈のアプリケーションであり、PEP 3107で文書化されています。構文セクションでは、キーワード引数がこのように関数注釈で機能することを明確にしています。

変更可能なキーワード引数を使用しないことを強くお勧めします。詳細はこちら


1
legacy.python.org/dev/peps/pep-3107/#syntaxを参照してください。型ヒントは、関数アノテーションの単なるアプリケーションです。
chepner

@chepner true。PEP 3107がキーワード引数について何かを持っていることを知りませんでした。
noɥʇʎԀʎzɐɹƆ

2
うわー、私はPythonの変更可能なデフォルト引数について知りませんでした...特にデフォルト引数が異なる動作をするJavascript / Rubyから来ています。SOの周りですでに言われていることについて、あれこれ言い直すのではなく、噛み付く前にこれを知ってよかったです。ありがとう!
josh

6
ディープコピーのないオブジェクトへの変更は反復間で持続するため、{}や[]などの変更可能な型やデフォルトオブジェクトではなく、Noneを使用するよう常にアドバイスされました。
MrMesees 2018年

2
可変キーワード引数で十分な関数を定義し、人生の選択を問う4時間のデバッグセッションを振り返るのは時間の問題です
Joseph Sheedy

20

あなたが使用している場合タイピングあなたが使用することができます(Pythonの3.5で導入されたが)typing.Optional、どこOptional[X]に相当しますUnion[X, None]。の明示的な値Noneが許可されていることを通知するために使用されます。入力から。オプション

def foo(arg: Optional[int] = None) -> None:
    ...

2
型ヒントのないキーワード引数の規則のように、=inの周りに空白を入れるべきではありませんOptional[int] = Noneか?
actual_panda

7

私は最近このワンライナーを見ました:

def foo(name: str, opts: dict=None) -> str:
    opts = {} if not opts else opts
    pass

こんにちは@Kirkalicious、回答ありがとうございます。それがどのように機能するか説明できますか?
Nathan

1
デフォルトのパラメータとして渡される空の辞書は、すべての呼び出しで同じ辞書です。したがって、関数がそれを変更した場合、デフォルトの次回は前回から変更された値になります。Noneデフォルトを作成してメソッド内をチェックすると、メソッドが呼び出されるたびに新しい辞書を割り当てることでこの問題を回避できます。
Ian Goldby
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.