私が使用しているオープンソースパッケージのソースコードを見てきました。ほとんどすべての関数は、名前付き引数の代わりに*argsを使用します。関数を呼び出すたびに、戻ってソースコードを選択し、引数の順序と引数を特定する必要があるため、コードを追跡して使用するのは難しいと感じています。私が持っている質問はこれです:すべての関数で* argsを使用する説得力のある理由がありますか、それともこれは概念の乱用ですか?ありがとう、-b
5 に答える
これは個人的な理由かもしれませんが、*args と **kwargs を使用するのは、いくつかのフィールドが特定のコンテキストでのみ使用されるオプション フィールドが多数ある場合のみです。
他に args を使用したのは、クラウド API 用の XML RPC クライアントを作成したときだけです。基になるレイヤーにパラメーターを渡すだけで、関数が動的に生成されたので、事前にすべてのパラメーターを知る方法がなかったため、*args を使用する以外に選択肢がありませんでした。
ほとんどの場合、それは必要ありません。私はそれが何よりも怠惰であると考えています。
Java や C# の出身者の中には、これを「params」の代わりに使用する人もいるかもしれませんが、Python でオプションのパラメーターを渡す方法はたくさんあります。
また、*args を使用する場合でも、非常に優れたドキュメントが必要であることに同意します。
すべての関数で使用*args
することは、コード内のエラー (間違った数の引数で関数を呼び出す) を隠す可能性があるため、悪い考えです。経験則として、必要な*args
場合にのみ使用する必要がある *args
と思います。
Zen of Pythonでは、暗黙的よりも明示的を好むように言われています。可能な限り、明示的な引数を使用する必要があります。
不明な関数をラップしている場合(デコレータによって返される関数がこれを行うことがよくあります)、多くの場合、を使用する必要があります(*args, **kwargs)
。
一部のクラス階層は(*args, **kwargs)
、階層内の異なるクラスで異なる署名を必要とする可能性のあるメソッドで使用します(__init__
これが主な原因です)。それを回避できれば非常に役立ちますが、複数の継承階層を適切な方法で(または少なくとも複数の継承で可能な限り適切に)処理する必要がある場合があります。
**kwargs
オプションの引数が多数ある場合に使用することがありますが、これには多くのドキュメントが必要です。
*args
(デコレータやクラス継承の場合のように、署名が不明な他の関数に渡すのではなく)それ自体を消費する関数では、 *args
「ゼロ以上の同じようなこと」。その場合は、。ではなく、*websites
または*spaceships
またはに名前を付ける必要があります。無関係なパラメータの束をに押しつぶしてはいけません。さらに悪いことに、関数が「x、ay、az、またはxとz」を取るために使用する場合、2番目のパラメーターは渡されるパラメーターの数に応じて異なることを行います。その時点で、それらは明らかにすべての名前とデフォルトを持っているはずです(それが単なる標準であっても)*watermelons
*args
*args
*args
None
デフォルトでは、関数でNone
パターン以外のものを確認し、位置ではなくキーワードで渡されます。
を使用するやむを得ない理由がない場合*args
、それは概念の乱用です。通常、引数には理解を助ける適切な名前があります。ない場合でも、(x, y, z)
以上のことを教えてくれます(*args)
。
また、コードを読みやすくするだけでなく、エラーをキャッチするのにも役立ちます (たとえば、 を使用して関数を呼び出すと、(x, y, z)
関数(2, 3)
の奥深くではなく、呼び出し時にエラーが発生します)。通常はより簡潔になり、もっと効率的。
しかし、 が広く使用されるには、やむを得ない理由がある場合があり*args
ます。
たとえば、下位レベル (C またはその他) のモジュールをラップしていて、完全な転送を行いたい場合は、*args
. ラッパー コードを手動で記述するのではなく、自動的に生成する場合はなおさらです。もちろん、これはまだトレードオフです。ラッパー モジュールの開発者にとってははるかに簡単ですが、ユーザーにとってはより困難です。ただし、トレードオフを考慮する価値がある場合もあります。
あなたが言及している特定のパッケージを知らなければ、それが説得力のあるユースケースなのか悪用なのかを推測することは不可能です.