См. следующий код:
def good():
foo[0] = 9 # why this foo isn't local variable who hides the global one
def bad():
foo = [9, 2, 3] # foo is local, who hides the global one
for func in [good, bad]:
foo = [1,2,3]
print('Before "{}": {}'.format(func.__name__, foo))
func()
print('After "{}": {}'.format(func.__name__, foo))
Результат выглядит следующим образом:
# python3 foo.py
Before "good": [1, 2, 3]
After "good": [9, 2, 3]
Before "bad" : [1, 2, 3]
After "bad" : [1, 2, 3]
Поскольку вы не устанавливаете foo, вы получаете что-то в foo (foo [0], чтобы быть точным).
В bad
вы создаете новую переменную foo
. В good
вы делаете что-то вроде foo.set(0, 9)
(установите значение 0 в значение 9). Который использует переменную и не определяет новое имя.
Если, как хорошо, вы хотите заменить содержимое списка foo, тогда вы можете назначить фрагмент всего списка, например:
def good2():
foo[:] = [9, 2, 3]
Так же, как и good
, назначенный одному элементу списка, это заменяет все содержимое.
В bad
вы привязывали список new к имени foo.
Чтобы сделать простой, python сначала посмотрим на локальные переменные и после в глобальных. (Для чтения или создания переменной)
Итак, в хорошем смысле вы берете переменную foo: нет локальной переменной foo и глобальной переменной foo = > вы берете глобальную и вы ее изменяете.
В противном случае вы создаете новую (локальную) переменную, поэтому глобальная не изменяется.
Вы можете указать, что переменная глобальна с ключевым словом global:
def good2():
global foo
foo = [9, 2, 3]
Переменные будут сначала смотреть на их внутреннюю область, а затем на внешние области в python. Например:
FOO = 'global'
def printfoo():
print FOO
# prints 'global'
def printfoolocal():
FOO = 'local'
print FOO
# prints 'local'
Если вы хотите изменить переменную с глобальным охватом, вам нужно использовать ключевое слово global
def modifyfoo():
global FOO
FOO = 'modified'
print FOO
# prints 'modified'