Почему я не могу заменить глобальные переменные из функции, с помощью должностного лица ()? Это хорошо работает, когда оператор присваивания за пределами должностного лица (). Вот пример моей проблемы:
>>> myvar = 'test' >>> def myfunc(): ... global myvar ... exec('myvar = "changed!"') ... print(myvar) ... >>> myfunc() test >>> print(myvar) test
на Документы , оператор , EXEC
принимает два дополнительных выражения, по умолчанию для глобал ()
и местных жителей ()
и всегда выполняет изменения (если есть) в местных жителей ()
.
Итак, просто будьте более явным / конкретным / точным ...:
>>> def myfunc():
... exec('myvar="boooh!"', globals())
...
>>> myfunc()
>>> myvar
'boooh!'
... И вы сможете сломать глобальные переменные в содержимое вашего сердца.
Как насчет этого:
>>> myvar = 'test'
>>> def myfunc():
... exec('globals()["myvar"] = "changed!"')
... print(myvar)
...
>>> myfunc()
changed!
>>> print(myvar)
changed!
Он работал для меня в Python 2.6.
Править: На самом деле объяснение Алекса Мартелли намного лучше моего :)
Чтобы добавить к ответу Алекса: хотя, когда вы опускаете аргументы locals/globals, они по умолчанию для locals и globals вызывающего абонента, это только удобный хак; это делает , а не , что означает, что они наследуют полный контекст выполнения вызывающего абонента. В частности:
a. вложенные ячейки области видимости недоступны исполняемому коду. Таким образом, это не удается:
def f():
foo= 1
def g():
exec('print foo')
g()
f()
b. Глобальные глобальные
декларации не переносятся в исполняемый код. Поэтому по умолчанию, как и в вашем примере, записанные переменные помещаются в локальный словарь. Однако, вы можете заставить это работать, сказав
exec('global myvar\nmyvar = "changed!"')
Вы на самом деле не захотите этого делать, если сможете помочь. global
уже некрасиво и exec
сам по себе пахнет кодом! Вы не захотите комбинировать их, если на самом деле нет альтернативы.