Установка переменных с exec внутри функции

Я только начал самостоятельно учить Python, и мне нужна небольшая помощь с этим сценарием:

old_string = "didnt work"   
new_string = "worked"

def function():
    exec("old_string = new_string")     
    print(old_string) 

function()

Я хочу получить это так old_string = "worked".

Ответ 1

Ты почти там. Вы пытаетесь изменить глобальную переменную, поэтому вам нужно добавить оператор global:

old_string = "didn't work"
new_string = "worked"

def function():
    exec("global old_string; old_string = new_string")
    print(old_string)

function()

Если вы запустите следующую версию, вы увидите, что произошло в вашей версии:

old_string = "didn't work"
new_string = "worked"

def function():
    _locals = locals()
    exec("old_string = new_string", globals(), _locals)
    print(old_string)
    print(_locals)

function()

выход:

didn't work
{'old_string': 'worked'}

Как вы его запустили, вы попытались изменить локальные переменные функции в exec, что по сути является неопределенным поведением. См. предупреждение в exec документах:

Примечание: Локальные пользователи по умолчанию действуют так, как описано для функции locals() ниже: не следует пытаться изменять словарь локальных языков по умолчанию. Передайте явный словарь локальных жителей, если вам нужно увидеть влияние кода на локальных жителей после того, как функция exec() вернется.

и соответствующее предупреждение на locals():

Примечание: Содержание этого словаря не должно быть изменено; изменения могут не влиять на значения локальных и свободных переменных, используемых интерпретатором.

Ответ 2

В качестве альтернативного способа обновления exec ваших глобальных переменных изнутри функции является передача globals() в нее.

>>> def function(command):
...    exec(command, globals())
...
>>> x = 1
>>> function('x += 1')
>>> print(x)
2

В отличие от locals(), обновление словаря globals() всегда должно обновлять соответствующую глобальную переменную, и наоборот.

Ответ 3

Я редактировал вопрос. Надеюсь, я хорошо понял этот вопрос.

Для этого вы можете просто сделать

old_string = new_string
print(old_string)
"worked"

Но я уверен, что это описано в любом учебнике...