2017-03-10 12 views
3

デフォルトの引数をとるPython関数fooがあるとします。そのデフォルトはグローバル変数に設定されています。関数を呼び出す前にグローバル変数を変更すると、デフォルト引数はそのグローバル変数の元の値に設定されたままです。例えばデフォルトの引数をグローバル変数として定義する

x = 1 

def foo(a=x): 
    print a 

x = 2 
foo() 

この代わり2の、1印刷します。

このグローバル変数を変更してこのデフォルト引数を更新できるように、コードをどのように書くべきですか?

+0

デフォルトの引数は、 –

答えて

4

デフォルト変数は、一度だけ評価され、に設定されます。だからPythonは参照のコピーを作成し、それ以降は常にその参照をデフォルト値として渡します。再評価は行われません。

別のオブジェクトを既定のオブジェクトとして使用して解決することができます。次にifステートメントを使用してそれに応じて置き換えます。以下のような何か:

the_default = object() 
x = 1 

def foo(a = the_default): 
    if a is the_default: 
     a = x 
    print a 

x = 2 
foo()

我々は参照の等価を実行するためにisを使用します。実際にdefault_objectかどうかを確認します。あなたのコードのどこかにthe_defaultオブジェクトを使用しないでください。

多くのPythonコードでは、デフォルトでNoneを使用しているため、オブジェクトの数が減ります。例えば:あなたはそれを行う場合

def foo(a = None): 
    if a is None: 
     a = x 
    print a

注しかし、あなたのプログラムはthe_objectはそれが難しく、ユーザーがそのオブジェクトへの参照を取得できるようになりようなものを使用したのに対し、foo()foo(None)を呼び出して、ユーザー間の区別をすることができません。 Noneが有効な候補でもある場合は、foo(None)'None'を入力し、xを入力しないと便利です。

+0

the_deaultとして 'None'を使用できます。私はそのコメントを書いたのと同じ瞬間に答えを更新しました。唯一の問題は、ユーザー自身がそのオブジェクトにフィードできるという事実を*除外したいということです。 'the_object'として何かを使うことで、あなたはその動作からより保護されます。 –

+1

@CarloLobrano:yesの値が有効でない限り、一度だけ評価されます。 –

+1

それが正しいです。時にはNoneよりも "default objects"を使う方が賢明です –

関連する問題