Переписывание переменных 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 или if?
  • Сохранять срок службы переменной после нескольких вызовов функций?
  • Область блока в Python
  • «Локальная переменная, на которую ссылаются до назначения» - только функции?
  • Область Python
  • Генерирование функций внутри цикла с выражением лямбда в python
  • Почему местность определяется во время компиляции?
  •  
    Interesting Posts for Van-Lav

    Почему я получаю формат «xyz», когда я печатаю список строк unicode в Python?

    Как написать пустой блок отступа в Python?

    Как я могу проверить, скомпилирован ли мой установленный numpy с помощью набора инструкций SSE / SSE2?

    Как наложить данные в течение «дневного периода» в Pandas для печати

    Проблема с Opencv и Python

    Py2exe ImportError: нет модуля с именем shell

    В Django, как я могу уведомить родителя, когда ребенок сохранен в отношении внешнего ключа?

    Миграция логистической регрессии от R до rpy2

    Обработка полиморфных исключений: как уловить исключение подкласса?

    Оператор умножения, применяемый к списку (структуре данных)

    Python / gspread – как я могу обновить несколько ячеек с РАЗЛИЧНЫМИ ЦЕННОСТЯМИ сразу?

    Pandas groupby и qcut

    Интересно 'принимает ровно 1 аргумент (2 заданный)' Ошибка Python

    Почему TimeoutError не создается в concurrent.futures.Future экземплярах

    Поиск первой производной с использованием DFT в Python

    Python - лучший язык программирования в мире.