Переписывание переменных Python во вложенных функциях

Предположим, у меня есть следующий код python:

def outer(): string = "" def inner(): string = "String was changed by a nested function!" inner() return string 

Я хочу, чтобы вызов external () возвращал «String был изменен вложенной функцией!», Но я получаю «». Я заключаю, что Python считает, что строка string = "string was changed by a nested function!" является объявлением новой переменной local to inner (). Мой вопрос: как я могу сказать Python, что он должен использовать строку external ()? Я не могу использовать global ключевое слово, потому что строка не является глобальной, она просто живет во внешней области. Идеи?

4 Solutions collect form web for “Переписывание переменных Python во вложенных функциях”

В Python 3.x вы можете использовать nonlocal ключевое слово:

 def outer(): string = "" def inner(): nonlocal string string = "String was changed by a nested function!" inner() return string 

В Python 2.x вы можете использовать список с одним элементом и перезаписать этот единственный элемент:

 def outer(): string = [""] def inner(): string[0] = "String was changed by a nested function!" inner() return string[0] 

Вы также можете обойти это, используя атрибуты функции:

 def outer(): def inner(): inner.string = "String was changed by a nested function!" inner.string = "" inner() return inner.string 

Уточнение: это работает как в python 2.x, так и в 3.x.

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

но у меня был опыт работы с анонимным объектом JAVA (т. е. определение runnable), и правило состояло в том, что анонимный объект создает жесткий экземпляр своей внешней среды, в этом случае переменные внешней области. Таким образом, если внешняя переменная является неизменяемой ( int , char ), они не могут быть изменены анонимным объектом, поскольку они копируются по значению, тогда как если его mutable ( collection , objects ), они могут быть изменены … поскольку они скопированы по « указателю » (их адрес в памяти)

если вы знаете о программировании, подумайте об этом как об ошибке и передайте по ссылке.

в python, это почти то же самое. x=123 – это назначение, они дают переменную xa новое значение (не изменяют старый x), list[i]/dict[key] – операции доступа к объекту, они действительно изменяют вещи

в заключение, вам нужен изменяемый объект … для изменения (хотя вы можете получить доступ к кортежу с помощью [], вы не можете использовать его здесь, так как он не изменяет)

Чтобы добавить к ответу Свена :

В Python 2.x вы можете читать только внешние переменные сферы из внутренней области. Присвоение просто создаст новую локальную переменную (то есть внутреннюю область), которая скрывает внешнюю область видимости.

Если вы хотите прочитать и изменить , вы можете использовать dict чтобы держать переменные во внешней области, а затем обращаться к ним через dict во внутренней области, также сохраняя ваш код довольно чистым и читаемым при наличии нескольких внешних областей видимости :

 def outer(): # hold some text, plus the number of spaces in the text vars = {'text': 'Some text.', 'num_spaces': 1} def inner(): # add some more text more_text = ' Then some more text.' vars['text'] += more_text # keep track of the number of spaces vars['num_spaces'] += more_text.count(' ') inner() return vars['text'], vars['num_spaces'] 

вывод:

 >>> outer() ('Some text. Then some more text.', 5) 
  • Области переменных в классах python
  • Сохранять срок службы переменной после нескольких вызовов функций?
  • Почему местность определяется во время компиляции?
  • Генерирование функций внутри цикла с выражением лямбда в python
  • Использование переменной в try, catch, finally statement без объявления ее вне
  • Измените функциональные переменные из внутренней функции в python
  • лямбда-функция, выходящая за пределы переменной
  • Как заставить локальную область в Python?
  • Python - лучший язык программирования в мире.