Язык программирования Python позволяет определять функции внутри других функций. Их часто называют вложенными функциями или внутренними функциями. Вот пример:
def parent(): print('=> parent') def child(): print('=> I child function') child() >>> parent() # => parent # => I child function
Каждый раз, когда вызывается функция parent()
, она определяет новую внутреннюю функцию child()
, затем вызывает ее.
Важно: внутренние функции не определены до тех пор, пока не будет вызвана родительская функция. Они локально ограничены родительской функцией parent()
. Они существуют только внутри функции parent()
как локальные переменные. Попробуйте вызвать child()
и получитe ошибку:
>>> child() # Traceback (most recent call last): # File "<stdin>", line 1, in <module> # NameError: name 'one_child' is not defined
Что если нужно получить доступ к вложенной функции извне? Функции - это объекты, следовательно можно вернуть внутреннюю функцию из вызывающей (родительской) функции.
Например, вот функция, определяющая две внутренние функции. В зависимости от аргумента, переданного функции верхнего уровня, она выбирает и возвращает вызывающей стороне одну из внутренних функций:
def talk(n): def hello(name): return f'Привет {name}.' def goodbye(name): return f'Пока {name}.' if n > 0: return hello else: return goodbye
Обратите внимание, что функция talk()
не вызывает ни одну из своих внутренних функций, talk()
просто выбирает соответствующую функцию на основе аргумента n
, а затем возвращает объект function
:
>>> talk(0) # <function talk.<locals>.goodbye at 0x7fb665af5598> >>> talk(1) # <function talk.<locals>.hello at 0x7fb66b1f58c8>
Можно вызвать возвращаемую функцию, либо напрямую, либо сначала присвоив ей имя переменной:
>>> say = talk(1) >>> say('Мир') # 'Привет Мир.' >>> talk(0)('Мир') # 'Пока Мир.'
Это означает, что функции могут не только принимать поведение через аргументы, но и могут возвращать поведение!