2017-06-12 14 views
2

私は、関数fct内のグローバルとしてリストcを宣言することなく、なぜこれが機能するのかを理解したいと思いますか?同じことが変数aに当てはまりませんか?Python - リスト変数の連結

def fct(): 
    global a  # have to declare this for "a" to work, but not for c[] 
    print(a,c) # by not declaring "a" as global, caused this to flag 
        # "accessing a without assignment", which I understand why, 
        # but why c[] needn't declaration 
    c[1]=5 
    a=234 

c=[0,0] 
a=11 
fct() 
+5

あなたは 'c'に割り当てていません。与えられたインデックスの値を設定するために、* it *に* cを変更しています。言い換えれば、 'c [...] = ...'は 'c = ...'と大きく異なります。 –

+0

https://stackoverflow.com/questions/291978/short-description-of-the-scoping-rules –

+0

短い答えはリストが変更可能であり、整数が不変であるためです。 – Anup

答えて

1

の実行前にそれらを宣言しているため、この質問は説明を少し必要があるかもしれませんオーケー関数本体にcaを宣言する必要はありません。

ネストスコープをサポートするほとんどの言語では、最も近い囲み範囲内の任意の名前を、コードを参照することができ、または(に割り当て)再バインド:

PEP 3104は、と述べています。現在のところ、Pythonコードは囲みスコープ内の名前を参照できますが、ローカルスコープ(単純な割り当て)またはモジュールグローバルスコープ(グローバル宣言を使用)の2つのスコープでのみ名前を再バインドできます。あなたはここで理解しておく必要があり

2つのことがあること:

  • 結合:、名前を作成し、それに値をバインドします。 たとえば>>> a=10 は変数aを作成し、それに10を割り当てます。

  • リバインディング:名前にバインドされた値を変更します。 >>> a=10;a=5 は値10をバインドし、5を 'a'自体にバインドします。

明示されているように、ローカルスコープ内でのみ名前を再バインドできます。

例:

def func(): 
    a=5 
    print(a) 
a=10 
print("a in the program") 
print(a) 
print("a in func()") 
func() 

は出力:

a in the program 
10 
a in func() 
5 

func()からa=5を削除して、あなたが得る:

a in the program 
10 
a in func() 
10 

a10、それであることを何が起こるのを発見されます印刷されます。あなたが関数内でa=5を与えるとどう

UnboundLocalError: local variable 'a' referenced before assignment 

:あなたがこれを取得

def func(): 
    print(a) 
    a=5 
a=10 
print("a in the program") 
print(a) 
print("a in func()") 
func() 

今これを行いますか?

いいえ再バインドの代わりに、新しいローカル変数a = 5が作成されるようになりました。

ので、

  • それだけで、デフォルトでグローバル変数aを印刷した後、/ print文の前にあなたがa=5を書いていない場合。

  • あなたがprint(a)a=5を書く場合は、それはaローカル変数を作成し、バインド(注意:再バインドが、バインドではない)値5それまでは。

  • しかしあなたはそれはあなたが変数(ローカル変数)まだ作成されていない参照している理由として混乱してしまうprint(a)a=5を書く場合。

名への割り当ては、暗黙的に名前がローカルであることを宣言ししかし、(グローバル宣言はグローバルであることを名前を強制する場合を除く)、外側のスコープに名前を再バインドことは不可能です。

ですから、global aを使用する場合、印刷は、(a)は喜ん10などのグローバルaを印刷し、その後に5を結合することによって、新たなローカル変数a=5を作成します。

global a 
print(a) 
a=5 
print(a) 

出力:

def func(): 
    global a 
    print(a) 
    a=5 
    print(a) 
a=10 
print("a in the program") 
print(a) 
print("a in func()") 
func() 

しかし、これはlistdictなどのようなあなたの他のオブジェクトとそうではありません。 この場合、通常の名前検索で見つかった既存のグローバルオブジェクトを変更しているだけです(リストエントリの変更はリストのメンバー関数を呼び出すようなものですが、名前の再バインドではありません)。

したがって、エラーは発生しません。あなたが何かを理解してもらいたいと思います

+0

これは 'global a'が必要な理由を説明しています。 OPはなぜ「グローバルc」が必要ではないかと尋ねた。 –

0

あなたは言葉globalを使用している場合、それはあなたがグローバル変数に書き込むことができることを意味しますが、私は、あなたはちょうどあなたがglobalを使用する必要はありません、それを読んでもらいたいです。

あなただけfct()

+0

バインディングの細かい点を指してくれてありがとうございます。 – ffrree