Вложенная функция в Python
какую пользу или последствия мы могли бы получить с кодом Python, как это:
class some_class(parent_class):
def doOp(self, x, y):
def add(x, y):
return x + y
return add(x, y)
Я нашел это в проекте с открытым исходным кодом, делая что-то полезное внутри вложенной функции, но ничего не делая вне ее, кроме вызова. (Фактический код можно найти здесь. Почему кто-то может его так закодировать? Есть ли какая-то польза или побочный эффект для написания кода внутри вложенной функции, а не во внешней, нормальной функции?
6 ответов
обычно вы делаете это, чтобы сделать закрытие:
def make_adder(x):
def add(y):
return x + y
return add
plus5 = make_adder(5)
print(plus5(12)) # prints 17
внутренние функции могут обращаться к переменным из заключительной области (в этом случае локальная переменная x
). Если вы не обращаетесь к переменным из заключительной области, они действительно являются обычными функциями с другой областью.
помимо функциональных генераторов, где внутреннее создание функций-это почти определение функционального генератора, причина, по которой я создаю вложенные функции, - это улучшение читаемости. Если у меня есть крошечная функция, которая будет вызываться только внешней функцией, тогда я вставляю определение, чтобы вам не пришлось пропускать, чтобы определить, что делает эта функция. Я всегда могу переместить внутренний метод за пределы метода инкапсуляции, если мне понадобится повторно использовать функцию позже дата.
игрушки например:
import sys
def Foo():
def e(s):
sys.stderr.write('ERROR: ')
sys.stderr.write(s)
sys.stderr.write('\n')
e('I regret to inform you')
e('that a shameful thing has happened.')
e('Thus, I must issue this desultory message')
e('across numerous lines.')
Foo()
одним из потенциальных преимуществ использования внутренних методов является то, что он позволяет использовать локальные переменные внешнего метода без передачи их в качестве аргументов.
def helper(feature, resultBuffer):
resultBuffer.print(feature)
resultBuffer.printLine()
resultBuffer.flush()
def save(item, resultBuffer):
helper(item.description, resultBuffer)
helper(item.size, resultBuffer)
helper(item.type, resultBuffer)
можно написать следующим образом, который, возможно, читает лучше
def save(item, resultBuffer):
def helper(feature):
resultBuffer.print(feature)
resultBuffer.printLine()
resultBuffer.flush()
helper(item.description)
helper(item.size)
helper(item.type)
Я не могу представить никакой веской причины для такого кода.
возможно, была причина для внутренней функции в более старых версиях, как и другие Ops.
например, это делает немного больше смысла:
class some_class(parent_class):
def doOp(self, op, x, y):
def add(x, y):
return x + y
def sub(x,y):
return x - y
return locals()[op](x,y)
some_class().doOp('add', 1,2)
но тогда внутренняя функция должна быть ("частными") методами класса вместо:
class some_class(object):
def _add(self, x, y):
return x + y
def doOp(self, x, y):
return self._add(x,y)
идея локальных методов похожа на локальные переменные: не загрязняйте большее пространство имен. Очевидно, что преимущества ограничены, поскольку большинство языков также не предоставляют такую функциональность напрямую.
вы уверены, что код был именно такой? Обычная причина для чего - то подобного-создание частичной функции с запеченными параметрами. Вызов внешней функции возвращает вызываемый объект, который не нуждается в параметрах, и поэтому может быть сохранен и использован где-то невозможно передать параметры. Однако код, который вы разместили, этого не сделает - он немедленно вызывает функцию и возвращает результат, а не вызываемый. Может быть полезно опубликовать фактический код вы видели.