2016-09-16 22 views
2

グローバル変数を誤って変更するのを避けるために、Pythonはグローバル変数に代入する前に明示的にglobalステートメントを必要とします。しかし、そのメソッドを呼び出すことによってグローバル変数を変更することは、特別なステートメントなしで行うことができます:グローバル変数:代入とメソッド呼び出し

x = [1, 2] 
y = [1, 2] 
def f(): 
    global x 
    x = x + [3] # won't affect global variable without global statement 
    y.append(3) # will affect global variable without global statement 

これはやや矛盾したようです。メソッドの呼び出しによってグローバルな変更可能なオブジェクトを変更するのは、新しいオブジェクト全体で置き換えるのと比べて、危険性は低いと評価されています。もしそうなら、なぜですか? documentationから

+2

。 http://stackoverflow.com/questions/6329499/in-python-why-is-list-automatically-global – MooingRawr

答えて

1

:関数の内部だけで参照されているPythonで

変数は暗黙的にグローバル です。 変数に値が割り当てられている場合は、関数 が関数本体内にあり、は がグローバルと明示的に宣言されていない限りローカルとみなされます。

あなたのケースでは、yは、関数の内部で参照されているため、暗黙的にグローバルです。一方、xには値が割り当てられているため、明示的に宣言されていない限りローカルでなければなりません。

およびドキュメントは、あなたの質問に答えるために、さらに行く:最初の

ビット意外ものの、一瞬の配慮が これを説明します。一方では、は、割り当てられた変数に対してグローバルを要求すると、意図しない副作用に対して のバーを提供します。一方、の場合は、すべてのグローバル参照でグローバルが である必要があります。グローバルではすべて の時間を使用しています。組み込みの 関数またはインポートされたモジュールのコンポーネントへのすべての参照をグローバルとして宣言する必要があります。この乱雑さは、 は、副作用を特定するためのグローバル宣言の有用性を打ち消します。

+0

ああ、私の質問で「y」を変更することは安全です、それはPythonインタープリタにとっては難しいことですインポートされたモジュールのコンポーネントにアクセスする比較的安全なケースとはっきり区別できますか? – max

+0

私はそれがPythonインタープリタにとって難しいとは思わないが、どのインタプリタにとっても難しいと思う。本質的には、私たちが自分たちの心の中で創り出すものを超えた違いはありません。 'Global'も名前の衝突を避けるための基本です。そうでなければ、私たちが書くすべての関数に異なる名前をつけなければなりません。 – dangom

+0

これは意味があります。 – max

0

値のレベルでは、実際にはそれを見ている方法ではありません。変数参照の変更可能性、すなわち名前付き項目(変数)が指しているものです。 yの上.append操作は名前が「Y」を指しているものを変更されていないのに対し、名前は「X」今、新しいもの(新しく作成されたリスト)を指していることを

x = [1, 2] 
print(id(x)) # 57226944 
y = [1, 2] 
print(id(y)) # 57262728 
def f(): 
    global x 
    x = x + [3] 
    print(id(x)) # 57306648 - CHANGED 
    y.append(3) 
    print(id(y)) # 57262728 - UNCHANGED 

f() 

注意。一つの文章で

0

「明示的に宣言せずに、Pythonはあなたがグローバル変数のreferenceを変更できません」。

ここで、読んだことを説明しましょう。変数へのオブジェクトの割り当ては、実際にはオブジェクトがメモリ内にあるメモリアドレスであるreferenceです。

我々は書く:実際にどこかのメモリ内のリストオブジェクトは、そのすべての関数参照とメンバーや他のたわごとに割り当てられていることを何が起こる

x = [1, 2] 

。このアドレスは実際にはxに保存されています。

私たちは、変化に気づくために機能id(object)を使用することがあります。これは助け

x = [1, 2] 
def foo(): 
print id(x) # an address like 50075016 
y = [1, 2, 3] 
print id(y) # another address like 50075272 
x = y   # won't work without declaring 'global x' 
       # because we try to change the address stored in x 
       # from 50075016 to 50075272. 
x.append(3) # works 
print id(x) # same address 50075016 
+0

もちろん、変数が指しているオブジェクトを変更するのと比べて、オブジェクトを変更するリスクが少ないのが私の疑問でした。 – max

関連する問題