1

なぜPythonは関数内のグローバル宣言されたリストを変更できないのですか?

再更新

numbers = []
num = 4

def add(n, thisnum=None):
    # changing global list without global declaration!
    numbers.append(n)
    if thisnum:
         num = thisnum
         print 'num assigned', thisnum
    ##numbers = ('one', 'two', 'three')
    ## adding this line makes error:
"""Traceback (most recent call last):
  File "J:\test\glob_vals.py", line 13, in <module>
    add(i)
  File "J:\test\glob_vals.py", line 6, in add
    numbers.append(n)
UnboundLocalError: local variable 'numbers' referenced before assignment
"""

for i in (1,2,3,564,234,23):
    add(i)

print numbers
add(10, thisnum= 19)
# no error
print num
# let the fun begin
num = [4]
add(10, num)
print num

# prints:
"""[1, 2, 3, 56, 234, 23]
num assigned 19
4
num assigned [4]
[4]

"""

同じ名前の変数に割り当てを行うと、追加された行ではなく、その行の前のアクションがエラーになります(バイトコードコンパイラがそれを見つけたと思います)。

4

3 に答える 3

5

グローバル変数に割り当てているのではなく、その内容を変更するメソッドを呼び出しています。これは許可されています。

globalキーワードなしではできないことは次のとおりです。

def add(n):
    #global numbers
    numbers = numbers + [n]

結果:

トレースバック (最新の呼び出しが最後):
  ファイル「C:\Users\Mark\Desktop\stackoverflow\python\test.py」の 8 行目
    追加(i)
  ファイル「C:\Users\Mark\Desktop\stackoverflow\python\test.py」の 5 行目を追加
    数字 = 数字 + [n]
UnboundLocalError: 代入前に参照されたローカル変数 'numbers'

違いは、ここでは既存のリストを変更していないことです。新しいリストを作成して、グローバル スコープに再割り当てしようとしています。globalしかし、これはキーワードなしでは実行できません。


更新について:

num次の行は、関数のスコープ内に新しいローカル名を作成するため、問題ありません。これは、グローバル スコープでの変数の値には影響しません。

num = thisnum
于 2010-12-11T17:11:20.067 に答える
1

global x 影響するだけです(つまり、独立したローカルを作成する代わりにx = ...、グローバルを再割り当てします)。それは影響しません(それはメソッド呼び出しであるため)または、Python(これは静的と動的の問題ではありません)は、これらのメソッドが何らかの方法で変更されることを知ることができない(そして気にしない)ためです。グローバル変数 (が指すオブジェクト) でのメソッド呼び出しを防ぐ必要があります...もちろん、これは無意味です。xxx.member = ...x.mutating_method(...)self

更新について: を行うときは、ローカル変数を作成し (を宣言しなかったため)、値を代入することとはnum = thisnumまったく異なることを行っています。これは、 global に触れることさえありません。numbers.append(n)global numnum

于 2010-12-11T17:15:41.337 に答える
0

リストに追加しているだけだからです。

アクセスと割り当ては異なる概念です。リストを追加するときは、その値を変更するメソッドを呼び出すだけです。あなたがしたと仮定すると+=、それは代入になります。

これを行う場合:

>>> numbers = []
>>> def add(n):
      numbers += n

>>> n = [1, 2]
>>> add(n)

これは割り当てであるため、失敗します。

これを修正するには、add()関数に次を追加します。

>>> def add(n):
        global numbers
        numbers += n
于 2010-12-11T17:11:24.563 に答える