Форум программистов, компьютерный форум, киберфорум
Python для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/3: Рейтинг темы: голосов - 3, средняя оценка - 4.67
37 / 31 / 13
Регистрация: 08.12.2012
Сообщений: 810

Вложенные функции

19.01.2025, 02:32. Показов 868. Ответов 13

Студворк — интернет-сервис помощи студентам
следующий код работает и после вызова выдает результат по стрелке -> 3
Python
1
2
3
4
5
6
def f(v):
    def f1():
        return v + 1
    return f1()
 
print(f(2)) -> 3
а в следующем, возникает ошибка, хотя переменную v
всего лишь убрали из return
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def f(v):
    def f1():
        v += 1
        return v 
    return f1()
 
print(f(2)) 
 
Traceback (most recent call last):
  File "D:\PYTHON\projects\stepic\new_2.py", line 7, in <module>
    print(f(2))
  File "D:\PYTHON\projects\stepic\new_2.py", line 5, in f
    return f1()
  File "D:\PYTHON\projects\stepic\new_2.py", line 3, in f1
    v += 1
UnboundLocalError: cannot access local variable 'v' where it is not associated with a value
и нужен nonlocal чтобы исправить
Python
1
2
3
4
5
6
7
8
def f(v):
    def f1():
        nonlocal v
        v += 1
        return v 
    return f1()
 
print(f(2))
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
19.01.2025, 02:32
Ответы с готовыми решениями:

Вложенные функции
Помгите разобраться. def myfunc(n): def myfuncx(x): def myfuncz(z): return z + x + n return...

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

Python вложенные функции
в чужих исходниках наткнулся на подобное: def make_configs_update(_type): def _update(instance): try: ...

13
Супер-модератор
Эксперт функциональных языков программированияЭксперт Python
 Аватар для Catstail
38167 / 21102 / 4307
Регистрация: 12.02.2012
Сообщений: 34,690
Записей в блоге: 14
19.01.2025, 08:48
ujif, всё верно. А в чём вопрос?
1
37 / 31 / 13
Регистрация: 08.12.2012
Сообщений: 810
19.01.2025, 14:53  [ТС]
Цитата Сообщение от Catstail Посмотреть сообщение
всё верно. А в чём вопрос?
вопрос следующий, почему в коде , который посередине, нужен nonlocal
ведь всего лишь из самого первого кода убрали из ретурна v+1
и прописали его вверху

здесь все работает
Python
1
2
3
4
5
6
def f(v):
    def f1():
        return v + 1
    return f1()
 
print(f(2)) -> 3
а в этом, всего лишь из ретурна убрали v+1
и прописали его сверху, почему здесь нужен nonlocal
чтобы не было ошибки, ведь ничего не изменилось по сути
Python
1
2
3
4
5
6
7
def f(v):
    def f1():
        v += 1
        return v 
    return f1()
 
print(f(2))
0
 Аватар для ViachaslauK
124 / 183 / 16
Регистрация: 08.10.2024
Сообщений: 664
19.01.2025, 15:23
Цитата Сообщение от ujif Посмотреть сообщение
и прописали его сверху, почему здесь нужен nonlocal
чтобы не было ошибки, ведь ничего не изменилось по сути
Вы пытаетсесь сделать инкремент для еще несуществующей переменной
Python
1
v += 1
когда вы добавляете
Python
1
nonlocal v
то вы эту переменную обявляете как, если не ошибаюсь enclosure

В самом первом варианте функция без обьявления считает v как enclosure и возвращает ее, добавив единицу.
Магическое слово для всего этого - LEGB
1
37 / 31 / 13
Регистрация: 08.12.2012
Сообщений: 810
19.01.2025, 19:49  [ТС]
Цитата Сообщение от ViachaslauK Посмотреть сообщение
Вы пытаетсесь сделать инкремент для еще несуществующей переменной
но разве эта переменная не найдя значение в локальной области,
не должна искать ее в объемлющей ее функции f(v) , зачем тут nonlocal
0
 Аватар для ViachaslauK
124 / 183 / 16
Регистрация: 08.10.2024
Сообщений: 664
19.01.2025, 20:40
Цитата Сообщение от ujif Посмотреть сообщение
но разве эта переменная не найдя значение в локальной области,
Нет, тут весь секрет в том как работает инкремент) Почитай ради интереса.
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
1.В Python существует правило LEGB для поиска переменных:
 
-Local (локальная область)
-Enclosing (область охватывающей функции)
-Global (глобальная область)
-Built-in (встроенная область)
 
Это я  вижу, ты знаешь. Дальше интересно:
 
2.Когда функция f1() пытается изменить v:
 
-Python создает локальную переменную
-Но она еще не имеет значения
-Отсюда ошибка UnboundLocalError
 
nonlocal указывает:
 
Переменная находится в охватывающей области
Разрешает изменение переменной из внешней функции
1
37 / 31 / 13
Регистрация: 08.12.2012
Сообщений: 810
19.01.2025, 21:12  [ТС]
Цитата Сообщение от ViachaslauK Посмотреть сообщение
nonlocal указывает
хорошо, это я понял, теперь другая проблема
почему в этом коде nonlocal не нужна или я действительно туплю
Python
1
2
3
4
5
6
def f(v):
    def f1():
        return v + 1
    return f1()
 
print(f(2)) -> 3
0
 Аватар для ViachaslauK
124 / 183 / 16
Регистрация: 08.10.2024
Сообщений: 664
19.01.2025, 22:11
Цитата Сообщение от ujif Посмотреть сообщение
почему в этом коде nonlocal не нужна или я действительно туплю
Перечитай внимательно мой предыдущий пост.
Ты здесь делаешь возврат нонлокал переменной. Тут как раз и работает как ты выше написал.
Цитата Сообщение от ujif Посмотреть сообщение
но разве эта переменная не найдя значение в локальной области,
не должна искать ее в объемлющей ее функции f(v)
Она и находит! берет v=2 и возвращает суммируя ее с единицей
Вернемся к LEGB
По отношению к f1 v является enclosure. то есть она на уровень выше. Ты можешь к ней обратиться, но не можешь ее модифицировать, не указав ее принадлежность.
Вот тебе пример. Поиграйся
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import inspect
 
i = 12
 
def outer(x):
    def inner():
        y = 7
        z = 10
        print(f'x = {x}')
        print(f'y = {y}')
        print(f'z = {z}')
        print(f'locals = {locals()}')
        print(f'globals = {globals()}')
        print(f'inspect = {inspect.currentframe().f_locals}')
        return x + y + z
    return inner
 
try:
    # Create closure
    closure_func = outer(5)
    
    # Execute closure
    result = closure_func()
    
    # Inspect closure variables
    closure_vars = inspect.getclosurevars(closure_func)
    print(f'Result = {result}')
    print(f'Closure vars = {closure_vars.nonlocals}')
    
except TypeError as e:
    print(f"TypeError occurred: {e}")
except Exception as e:
    print(f"Unexpected error: {e}")
1
37 / 31 / 13
Регистрация: 08.12.2012
Сообщений: 810
19.01.2025, 22:22  [ТС]
Цитата Сообщение от ViachaslauK Посмотреть сообщение
Вот тебе пример. Поиграйся
спасибо конечно за пример, он для меня очень сложный ,
я написал всего 2 простых кода и хотел получить простой ответ
почему в этом случае, когда v написано в ретурне , все работает
Python
1
2
3
4
5
6
def f(v):
    def f1():
        return v + 1
    return f1()
 
print(f(2)) -> 3
а в следующем, всего лишь увеличение переменной перенесли
и записали выше ретурна, а в ретурне оставили возврат значения
и тут вдруг понадобился nonlocal
ведь по сути ничего не изменилось
Python
1
2
3
4
5
6
7
8
def f(v):
    def f1():
        nonlocal v
        v += 1
        return v 
    return f1()
 
print(f(2))
ладно может найдется , кто объяснит мне тупому , как попроще
спасибо за ваше время и попытки
0
Любознательный
 Аватар для YuS_2
7404 / 2254 / 360
Регистрация: 10.03.2016
Сообщений: 5,213
20.01.2025, 04:07
Лучший ответ Сообщение было отмечено ujif как решение

Решение

Цитата Сообщение от ujif Посмотреть сообщение
v += 1
это эквивалент:
Python
1
v = v + 1
- т.е. сложение значения переменной с единицей и записью этой суммы в эту переменную, в общем это прямое изменение переменной. В этом случае, если переменной не существует в локальной области или переменная не объявлена как существующая вне локальной области, то будет выдано исключение.

Цитата Сообщение от ujif Посмотреть сообщение
Python
1
2
3
...
        return v + 1
...
Здесь значение переменной не изменяется. Это возврат суммы значения переменной с единицей.
Получить значение переменной из не локальной области, в Питоне можно и без объявления, но для изменения такой переменной, необходимо предварительно объявить, что переменная не локальная.
Если попроще, то почувствуйте разницу:
Python
1
v + 1
и
Python
1
v = v + 1
3
 Аватар для ViachaslauK
124 / 183 / 16
Регистрация: 08.10.2024
Сообщений: 664
20.01.2025, 09:41
Цитата Сообщение от YuS_2 Посмотреть сообщение
но для изменения такой переменной, необходимо предварительно объявить, что переменная не локальная.
А для этого нужно знать, как происходит создание переменной в пайтон. Алгоритм примерно так можно описать
# В момент a = a + 1:
# 1. Python видит присваивание и помечает 'a' как локальную
# 2. Затем пытается найти значение 'a' справа
# 3. Но 'a' уже помечена как локальная и еще не имеет значения
# 4. Возникает UnboundLocalError

Обьявив переменную как nonlocal мы даем интрепретатору указание искать переменную в enclosure области
А можно копнуть еще глубже и посмотреть вообще, что такое переменная в Пайтон.
1
Любознательный
 Аватар для YuS_2
7404 / 2254 / 360
Регистрация: 10.03.2016
Сообщений: 5,213
20.01.2025, 10:45
Цитата Сообщение от ViachaslauK Посмотреть сообщение
А для этого нужно знать, как происходит создание переменной в пайтон.
Абсолютно не нужно... только если из любопытства.

Цитата Сообщение от ViachaslauK Посмотреть сообщение
Обьявив переменную как nonlocal мы даем интрепретатору указание искать переменную в enclosure области
Спасибо, кэп. Только я не просил объяснять объясненное
1
 Аватар для ViachaslauK
124 / 183 / 16
Регистрация: 08.10.2024
Сообщений: 664
20.01.2025, 11:04
Исправлено
Сорри за ответ не по теме и не по адресу. НЕ глядя написал.
1
37 / 31 / 13
Регистрация: 08.12.2012
Сообщений: 810
20.01.2025, 13:19  [ТС]
Цитата Сообщение от YuS_2 Посмотреть сообщение
Если попроще, то почувствуйте разницу
спасибо огромное, просто и внятно объяснили
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
20.01.2025, 13:19
Помогаю со студенческими работами здесь

Вложенные функции Python
Подскажите есть 2 функции, одна в другой, как сделать запуск первой функции только если выполнено определенное условие вложенной функции,...

Вложенные функции
А если функция объявлена как-то иначе например f = function(){} она может быть вложенной более чем на один уровень?

вложенные функции
Помогите с задачкой, очень прошу, пожалуйста!

Вложенные функции
Собственно сабж. Есть общая функция для открытия диалогового окна через jQuery, у этой функции несколько параметров: title - текст...

Вложенные функции
&lt;html&gt;&lt;body&gt; &lt;?php function father($a){ echo $a, &quot;&lt;br&gt;&quot;; function child($b){ echo $b+1,&quot;&lt;br&gt;&quot;; return $b * $b; ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Новые блоги и статьи
Первый деплой
lagorue 16.01.2026
Не спеша развернул своё 1ое приложение в kubernetes. А дальше мне интересно создать 1фронтэнд приложения и 2 бэкэнд приложения развернуть 2 деплоя в кубере получится 2 сервиса и что-бы они. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь постоянного тока с R, L, C, k(ключ), U, E, J. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа, решает её и находит токи на L и напряжения на C в установ. режимах до и. . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Изучаю kubernetes
lagorue 13.01.2026
А пригодятся-ли мне знания kubernetes в России?
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru