Что является эквивалентом передачи функций в качестве аргументов с использованием объектно-ориентированного подхода

У меня есть программа на Python, которая включает в себя класс, который принимает функцию в качестве аргумента __init__ метод. Эта функция хранится как атрибут и используется в различных местах в классе. Передаваемые функции могут быть весьма разнообразными, и передача ключа, а затем выбор из набора предопределенных функций не даст такой же степени гибкости.

Теперь, извините, если длинный список вопросов, как это не круто, но...

  • Являются ли они стандартным способом достижения этого в языке, где функции не являются объектами первого класса?
  • Считают ли блоки в этом отношении функциями, как в smalltalk или target-C?
  • Будут ли блоки лучшим способом сделать это на этих языках?
  • Что делать, если нет блоков?
  • Не могли бы вы добавить новый метод во время выполнения?
  • На каких языках это возможно (и легко)?
  • Или было бы лучше создать объект с единственным методом, который выполняет желаемую операцию?
  • Что если бы я хотел передать много функций, я бы создал много одноэлементных объектов?
  • Будет ли это рассматриваться как более объектно-ориентированный подход?
  • Кто-нибудь подумал бы сделать это в Python, где функции являются объектами первого класса?

4 ответа

Решение

Я не понимаю, что вы подразумеваете под "эквивалентным... используя объектно-ориентированный подход". В Python, поскольку функции (как вы говорите) являются объектами первого класса, как это не "объектно-ориентировано" передавать функции в качестве аргументов?

стандартный способ достичь этого в языке, где функции не являются объектами первого класса?

Я бы сказал, только в той степени, в которой существует стандартный способ, при котором функции не могут быть первоклассными объектами.

В C++ обычно создают другой класс, часто называемый функтором или функционалом, который определяет перегрузку для operator(), позволяя использовать экземпляры как функции синтаксически. Тем не менее, также часто можно обойтись с простыми старыми указателями на функции. Ни указатель, ни указанная функция не являются первоклассным объектом, но интерфейс достаточно богат.

Это хорошо согласуется с "специальным полиморфизмом", достигнутым с помощью шаблонов; вы можете писать функции, которым на самом деле все равно, передаете ли вы экземпляр класса или указатель на функцию.

Аналогично, в Python вы можете сделать так, чтобы объекты регистрировались как callable определив __call__ метод для класса.

Считают ли блоки в этом отношении функциями, как в smalltalk или target-C?

Я бы сказал, что они делают. По крайней мере столько же, сколько лямбда считает функциями в Python, и даже больше, потому что они не повреждены, как лямбды Python.

Будут ли блоки лучшим способом сделать это на этих языках?

Это зависит от того, что вам нужно.

Не могли бы вы добавить новый метод во время выполнения? На каких языках это возможно (и легко)?

Языки, которые предлагают самоанализ и доступ во время выполнения к своему собственному компилятору. Питон готов.

Тем не менее, в этой проблеме нет ничего, что было представлено, что наводит на мысль о необходимости перепрыгивать через такие обручи. Конечно, для некоторых классов в некоторых языках требуется больше шаблонов, чем в других.

Или было бы лучше создать объект с единственным методом, который выполняет желаемую операцию?

Это довольно стандартно.

Что если бы я хотел передать много функций, я бы создал много одноэлементных объектов?

Вы говорите это так, как будто вы можете каким-то образом случайно создать более одного экземпляра класса, если вы не пишете тонны стандартного шаблона, пытаясь помешать себе это сделать.

Будет ли это рассматриваться как более объектно-ориентированный подход?

Опять же, я не могу понять ваше понимание термина "объектно-ориентированный". Это не означает "создание множества объектов".

Кто-нибудь подумал бы сделать это в Python, где функции являются объектами первого класса?

Не без необходимости в дополнительных вещах, которые класс может делать, а функция - нет. С утки печатать, с какой стати вы беспокоитесь?

Я просто собираюсь ответить на некоторые ваши вопросы.

Как говорят в сообществе Scheme, "объекты - это замыкания бедняков" (замыкания - первоклассные функции). Блоки обычно просто синтаксический сахар для укупорки. Для языков, которые не имеют замыканий, существуют различные решения.

Одним из распространенных решений является использование перегрузки операторов: в C++ есть понятие объектов функций, которые определяют член operator() ("вызов функции оператора"). Python имеет похожий механизм перегрузки, где вы определяете __call__:

class Greeter(object):
    def __init__(self, who):
         self.who = who

    def __call__(self):
         print("Hello, %s!" % who)

hello = Greeter("world")
hello()

Да, вы можете рассмотреть возможность использования этого в Python вместо хранения функций в объектах, так как функции не могут быть выбраны.

На языках без перегрузки операторов вы увидите такие вещи, как Guava Function интерфейс.

Вы можете использовать шаблон стратегии. В основном вы передаете объект с известным интерфейсом, но другим поведением. Это как передача функции, но она заключена в объекте.

В Smalltalk вы в основном будете использовать блоки. Вы также можете создавать классы и экземпляры во время выполнения.

Другие вопросы по тегам