Вложенная функция в 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)
идея локальных методов аналогична локальным переменным: не загрязняйте большее пространство имен. Очевидно, что преимущества ограничены, поскольку большинство языков также не предоставляют такую функциональность напрямую.
вы уверены, что код был именно такой? Обычная причина для выполнения чего - то подобного заключается в создании частичной функции с запеченными параметрами. Вызов внешней функции возвращает вызываемый объект, который не нуждается в параметрах, и поэтому может быть сохранен и использован где-то, где невозможно передать параметры. Однако код, который вы опубликовали, не будет этого делать-он немедленно вызывает функцию и возвращает результат, а не вызываемый. Может быть полезно опубликовать фактический код вы видели.
Comments