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

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

Теперь, извиняюсь, если длинный список подобных вопросовне круто, но ...

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

Ответы [ 4 ]

1 голос
/ 03 ноября 2011

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

1 голос
/ 03 ноября 2011

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1 голос
/ 03 ноября 2011

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

Как говорят в сообществе 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 вместо хранения функций в объектах, поскольку функции не могут быть маринованными .

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

0 голосов
/ 08 ноября 2011

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

...