Не может заменить глобальные переменные в функции через должностное лицо () оператор?

Почему я не могу заменить глобальные переменные из функции, с помощью должностного лица ()? Это хорошо работает, когда оператор присваивания за пределами должностного лица (). Вот пример моей проблемы:

>>> myvar = 'test'
>>> def myfunc():
...     global myvar
...     exec('myvar = "changed!"')
...     print(myvar)
... 
>>> myfunc()
test
>>> print(myvar)
test
21
задан linkmaster03 18 January 2010 в 01:12
поделиться

3 ответа

на Документы , оператор , EXEC принимает два дополнительных выражения, по умолчанию для глобал () и местных жителей () и всегда выполняет изменения (если есть) в местных жителей () .

Итак, просто будьте более явным / конкретным / точным ...:

>>> def myfunc():
...   exec('myvar="boooh!"', globals())
... 
>>> myfunc()
>>> myvar
'boooh!'

... И вы сможете сломать глобальные переменные в содержимое вашего сердца.

29
ответ дан 29 November 2019 в 20:55
поделиться

Как насчет этого:

>>> myvar = 'test'
>>> def myfunc():
...     exec('globals()["myvar"] = "changed!"')
...     print(myvar)
... 
>>> myfunc()
changed!
>>> print(myvar)
changed!

Он работал для меня в Python 2.6.

Править: На самом деле объяснение Алекса Мартелли намного лучше моего :)

3
ответ дан 29 November 2019 в 20:55
поделиться

Чтобы добавить к ответу Алекса: хотя, когда вы опускаете аргументы locals/globals, они по умолчанию для locals и globals вызывающего абонента, это только удобный хак; это делает , а не , что означает, что они наследуют полный контекст выполнения вызывающего абонента. В частности:

a. вложенные ячейки области видимости недоступны исполняемому коду. Таким образом, это не удается:

def f():
    foo= 1
    def g():
        exec('print foo')
    g()
f()

b. Глобальные глобальные декларации не переносятся в исполняемый код. Поэтому по умолчанию, как и в вашем примере, записанные переменные помещаются в локальный словарь. Однако, вы можете заставить это работать, сказав

exec('global myvar\nmyvar = "changed!"')

Вы на самом деле не захотите этого делать, если сможете помочь. global уже некрасиво и exec сам по себе пахнет кодом! Вы не захотите комбинировать их, если на самом деле нет альтернативы.

4
ответ дан 29 November 2019 в 20:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: