呼び出された関数は、デフォルト値であるか渡されたものであるかにかかわらず、最後の引数値のみを取得します。したがって、呼び出し元が何かを渡したかどうかを判断できるようにするために必要なことは、デフォルト値を渡せないものにすることです。の。
彼らは渡すNone
ことができるので、あなたはそれを使うことができません。何が使えますか?
最も簡単な解決策は、ある種のPythonオブジェクトを作成し、それを関数のデフォルト値として使用することですdel
。そうすると、ユーザーはそれを参照できなくなります。技術的には、ユーザーはこれを関数オブジェクトから掘り下げることができますが、そのような長さになることはめったにありません。そうする場合は、取得する価値があると主張できます。
default = []
def foo(a=default):
if a is default:
a = 10
print a
del default
ここで使用している「デフォルト値」は空のリストです。リストは変更可能であるため、再利用されることはありません。つまり、空のリストはそれぞれ一意のオブジェクトです。(Pythonは、実際にはすべての空のタプルに同じ空のタプルオブジェクトを使用するため、空のタプルを使用しないでください。文字列リテラルと小さい整数も同様に再利用されるため、これらも使用しないでください。)object
インスタンスは問題ありません。変更可能であり、したがって共有されない限り、何でも。
問題は、上記のコードが実行されてから実際に実行されないことですdel default
。実行時に関数でこのオブジェクトへの参照を取得して、それに対してテストできるようにするにはどうすればよいですか?これを行う1つの方法は、実際の引数には使用されないデフォルトの引数値を使用することです。
default = []
def foo(a=default, default=default):
if a is default:
a = 10
print a
del default
これにより、関数の定義時にオブジェクトが引数のデフォルト値にバインドされるため、グローバル名が1秒後に削除されても問題ありません。しかし、誰かがhelp()
あなたの関数を実行したり、それを内省したりすると、彼らが渡すことができる追加の引数があるように見えるという問題があります。より良い解決策はクロージャです。
default = []
def foo(default=default): # binds default to outer func's local var default
def foo(a=default): # refers to outer func's local var default
if a is default:
a = 10
print a
return foo
foo = foo()
del default
これはすべてかなり多くの作業を行う必要があるため、実際には気にしないでください。