У меня ошибка когда вызываю функцию который внутри себя имеет еще одну функцию

Код:

def list_box():
    num = 87 
    def inner_box():
       num_2 = 65 
       print(num+num_2)

list_box(inner_box())

Ошибка:

list_box(inner_box())
NameError: name 'inner_box' is not defined

Как это исправить. Как вызвать внутри функции еще одну функцию


Ответы (3 шт):

Автор решения: insolor

Вложенные функции не доступны по имени снаружи "родительских" функций. Чтобы вызвать внутреннюю функцию, можно дописать внутри внешней функции вызов внутренней функции (вариант 1), можно вернуть внутреннюю функцию из внешней функции через return, потом снаружи это значение вызвать как функцию (вариант 2) - все зависит от того, что конкретно вы пытаетесь сделать.

# Вариант 1
def list_box():
    num = 87 
 
    def inner_box():
       num_2 = 65 
       print(num+num_2)
 
    inner_box() 
 
 
list_box()  # вывод: 152
 
 
# Вариант 2
def list_box():
    num = 87 
 
    def inner_box():
       num_2 = 65 
       print(num+num_2)
 
    return inner_box
 
 
list_box()()  # вывод: 152

# В отдельных строках, чтобы было понятно, что тут происходит:
function = list_box()
function()

https://ideone.com/FKQ5jO

→ Ссылка
Автор решения: GrAnd

Не совсем ответ на поставленный вопрос, просто информации для...

Если по каким-то причинам всё-таки нужно вызвать вложенную функцию напрямую (без задействования "родительской") - это возможно. Но для этого как минимум нужно заново переопределить локальные переменные "родительской" функции которые используются во вложенной.

Пример того, как это возможно сделать:

def list_box():
    num = 87 
    def inner_box(x):
       num_2 = 65 
       print(f'num = {num}\nnum_2 = {num_2}\nx = {x}\nnum+num_2*x = {num+num_2*x}')


# а теперь - "грязные хаки" :)
import types 

def call_nested(outer, inner_name, **vars):
    def var_wrap(val):
        def var_closure():
            return val
        return var_closure.__closure__[0]

    for code in outer.__code__.co_consts:
        if isinstance(code, types.CodeType) and code.co_name == inner_name:
            return types.FunctionType(code, globals(), None, None, tuple(var_wrap(vars[name]) for name in code.co_freevars))

call_nested(list_box, 'inner_box', num=11)(2)

Вывод:

num = 11
num_2 = 65
x = 2
num+num_2*x = 141
→ Ссылка
Автор решения: Tea Mint

Вот решение

def list_box():
    num = 87
    def inner_box():

        num2 = 65
        print(num+num2)
    return inner_box()


list_box()
→ Ссылка