2011-01-01 17 views
16

私は2つの引数をとるPython関数を持っていると仮定しますが、2番目の引数はオプションで、デフォルトは最初の引数として渡されます。だから、私はこのような何かをしたい:Pythonでは、他の引数に関して関数の引数のデフォルトを指定できますか?

def myfunc(arg1, arg2=arg1): 
    print (arg1, arg2) 

それ以外は動作しません。私が考えることができる唯一の回避策は次のとおりです。

def myfunc(arg1, arg2=None): 
    if arg2 is None: 
     arg2 = arg1 
    print (arg1, arg2) 

これを行うより良い方法はありますか?

+0

私はちょうどこれを考え直しているかもしれませんが、デコレータで達成することは可能かもしれません。それは一見すると分かりにくいので、おそらく悪い考えですが、それは考えです。 – marcog

答えて

17

@Ignacioによると、これはできません。後者の例では、arg2の有効値はNoneです。この場合は、センチネル値を使用することができます:

sentinel = object() 
def myfunc(arg1, arg2=sentinel): 
    if arg2 is sentinel: 
     arg2 = arg1 
    print (arg1, arg2) 

myfunc("foo")   # Prints 'foo foo' 
myfunc("foo", None)  # Prints 'foo None' 
+2

@martineau編集していただきありがとうございます。 – marcog

+2

いいえ、問題ありません。 – martineau

+0

おそらく、arg2をNoneにデフォルト設定して、ユーザーを処理する必要がない限り、カスタム・センチネル・オブジェクトで悩むのではなく、そのことを確認することをお勧めします。 – user234461

3

関数が実際に入力されるまで、他の引数名は存在しません。

+0

しかし、回避策の 'if'節を' arg2 = arg2 or arg1'に変更することで、わずかに整理できます。 –

+1

@Michael 'arg2'が' 0'、 'False'または空のシーケンスであれば失敗します。 – marcog

3

私の意見では2番目の方法は、あなたが何をしているのか、そしてあなたを追いかけてコードを読んでくれるすべての人にとって、正しいことです。 デフォルトの動作を文書化する際に若干のオーバーヘッドがありますが、「なし」などを使用して関数をデフォルト値にすることは非常に一般的です。関数呼び出しの中にロジックを置くことは、私の見解では賞賛に値するものではないでしょう。すぐに非常に複雑になる可能性があります。だから、すべてのコードがある関数本体に残しておきます。