2016-05-06 6 views
-1

私がfunc1で再帰呼び出しで変数のスコープのpython3は

def func1(var): 
    if var == 0: 
     return 
    else 
     var = var - 1 
     func1(var) 

PROPOSAL = 1 

def func2(): 
    func1(PROPOSAL) 
    print(PROPOSAL) 

は、変数PROPOSALprint文が0を出力します意味、デクリメントされますか?

編集:私は尋ねたはずですが、なぜこれをしないのですか?

+0

これを試したときに何が起こったのですか? –

答えて

0

内のスコープはありません、PROPOSALグローバル変数は、コードデクリメントされないこと、それを変更していなかったPROPOSAL変数を出力します。これはスコープが原因ではありませんが、Pythonが引数をどのように渡すかが原因です。

引数をとる関数を呼び出すと、渡す引数の値は、変数への代入と同様に、パラメータ名にバインドされます。値が可変であれば、1つの名前によるインプレース修正が他の名前から見えますが、変数が不変の場合(intはPythonにあります)、1つの変数への変更が別のものに影響することはありません。ここで

が同じよう取り組ん機能と定期的な割り当てを示す例です:もちろん

x = 1 

y = x # binds the y to the same value as x 
y += 1 # modify y (which will rebind it, since integers are immutable) 
print(x, y) # prints "1 2" 

def func(z): # z is a local variable in func 
    z += 1 
    print(x, z) 
func(x) # also prints "1 2", for exactly the same reasons as the code above 

X = [1] 

Y = X # again, binds Y to the same list as X 
Y.append(2) # this time, we modify the list in place (without rebinding) 

print(X, Y) # prints "[1, 2] [1, 2]", since both names still refer to the same list 

def FUNC(Z): 
    Z.append(3): 
    print(X, Z) 
FUNC(X) # prints "[1, 2, 3] [1, 2, 3]" 

を、変更可能な値に言及変数を再バインドすることも、他の参考文献には反映されていない変更が発生します元の値。たとえば、コードの2番目の部分のappend()コールをY = Y + [2]Z = Z + [3]に置き換えた場合、元の値を変更するのではなく、Xリストは変更されません。これらの割り当てステートメントはYZに再バインドされるため変更されません。

+=,-=、および*=のような「拡張割り当て」演算子はちょっと難しいです。彼らは、左側の値がそれをサポートしている場合(そして多くの変更可能な型がそうである場合)、インプレース修正を最初に試みます。値がその種類のインプレース変更をサポートしていない場合(たとえば、不変オブジェクトまたは特定の演算子が許可されていないなど)、通常の+演算子を使用して新しい値を作成し直します(それでも失敗した場合は、例外が発生します)。

0

func1(PROPOSAL)はNONEを返し、その戻り値をPROPOSALに割り当てないため、グローバルPROPOSAL変数には影響しません。

func2()はちょうど()関数func1を呼び出し、そしてちょうどfunc1(PROPOSAL)