Ваш вопрос вызвал у меня любопытство, поэтому я заглянул в некоторый реальный код: стандартную библиотеку Python. Я нашел 67 примеров вложенных функций. Вот несколько с объяснениями.
Одна очень простая причина для использования вложенной функции заключается в том, что определяемая вами функция не обязательно должна быть глобальной, потому что ее использует только включающая функция. Типичный пример из стандартного библиотечного модуля Python quopri.py :
def encode(input, output, quotetabs, header = 0):
...
def write(s, output=output, lineEnd='\n'):
# RFC 1521 requires that the line ending in a space or tab must have
# that trailing character encoded.
if s and s[-1:] in ' \t':
output.write(s[:-1] + quote(s[-1]) + lineEnd)
elif s == '.':
output.write(quote(s) + lineEnd)
else:
output.write(s + lineEnd)
... # 35 more lines of code that call write in several places
Здесь был некоторый общий код в функции encode
, поэтому автор просто преобразовал его в функцию write
.
Другое распространенное использование для вложенных функций - re.sub
. Вот код из стандартного библиотечного модуля json / encode.py :
def encode_basestring(s):
"""Return a JSON representation of a Python string
"""
def replace(match):
return ESCAPE_DCT[match.group(0)]
return '"' + ESCAPE.sub(replace, s) + '"'
Здесь ESCAPE
- регулярное выражение, а ESCAPE.sub(replace, s)
находит все совпадения ESCAPE
в s
и заменяет каждое на replace(match)
.
Фактически, любой API, например re.sub
, который принимает функцию в качестве параметра, может привести к ситуациям, когда вложенные функции удобны. Например, в turtle.py есть некоторый глупый демонстрационный код, который делает это:
def baba(xdummy, ydummy):
clearscreen()
bye()
...
tri.write(" Click me!", font = ("Courier", 12, "bold") )
tri.onclick(baba, 1)
onclick
ожидает, что вы передадите функцию обработчика событий, поэтому мы определим ее и передадим.