Вложенная функция в Python



какую пользу или последствия мы могли бы получить с помощью кода Python следующим образом:



class some_class(parent_class):
def doOp(self, x, y):
def add(x, y):
return x + y
return add(x, y)


Я нашел это в проекте с открытым исходным кодом, делая что-то полезное внутри вложенной функции, но не делая абсолютно ничего вне нее, кроме ее вызова. (Фактический код можно найти здесь.) Почему кто-то может закодировать его так? Есть ли какое-то преимущество или побочный эффект для написания кода внутри вложенной функции, а не во внешней, нормальной функции?

264   6  

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

    Ничего не найдено.