Есть ли смысл в контейнере внедрения зависимостей в Python? - PullRequest
16 голосов
/ 30 июля 2011

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

Я понимаю смысл этих контейнеров в статически типизированных ОО-языках, таких как Java и C #, но где такая вещь вписалась бы в безумный мир python (мне это нравится)?

Я всегда подозревал, что инъекция зависимости как шаблон дизайна была дурным запахом, который был создан всем, должен быть классом "нацистского мышления", который является c # и Java, я был бы прав, или я что-то упускаю?

До сих пор я думаю, что могу покрыть фабрики, Singletons, Multi-instance объекты, просто используя Globals. Я также подозреваю, что материал Aspect тоже покрыт, хотя я все еще думаю об этом.

Duck Typing - это то, что меня сейчас привлекает, поэтому я привык определять интерфейсы, основывать классы на этих интерфейсах и позволять статическим вещам покрывать мою глупость, и я чувствую, что без статической типизации контейнеры немного бесполезны.

1012 * редактировать *

Я думаю, что не буду использовать фреймворки / контейнеры Dependency Injector при использовании python. Там действительно нет никакого смысла. После обдумывания и прочтения ответов до сих пор, аргумент становится понятным, что без статических определений типов сделанные обещания настолько бесполезны, что вообще бесполезны. Утиная печать - это то, что есть, и единственное обещание можно сделать с помощью документации. Пока ссылка входит в класс Method / function через параметр signiture, а не через эфир среды программирования, я думаю, что я буду в безопасности.

Тревожным является тот факт, что я не могу навязать свою волю другим через свои чрезмерные методы проектирования, как я это делал в Java и C #. Меня это волнует ...... нет :)

Ответы [ 2 ]

13 голосов
/ 30 июля 2011

не имеет полезной концепции программирования на основе интерфейса (как в интерфейсах C #)

То, что компилятор не может проверить, правильно ли вы используете интерфейс, не означает, чтоmsgstr "нет полезной концепции интерфейсов".Вы документируете интерфейс и пишете модульные тесты.

Что касается глобалов, то не похоже, чтобы public static методы и поля в классах C # или Java действительно отличались.Рассмотрим, например, как работает java.lang.Math.Теперь рассмотрим тот факт, что java.lang.Math не синглтон.Они сделали это по уважительной причине.

При всех этих вкусностях действительно есть какой-то смысл в контейнере для инъекций зависимостей

Я сомневаюсь в этом, но тогда я так и не увиделсмысл их в C # или Java, либо.Внедрение зависимости - это, на мой взгляд, методика .И в этом тоже нет ничего особенного.

Я всегда подозревал, что инъекция зависимости как шаблон дизайна была дурным запахом, который создавался всем, должен быть классом «нацистского мышления»

Нет, это не так.Внедрение зависимостей - хорошая идея в большинстве случаев.Вам также не нужен класс для внедрения зависимостей.Каждый раз, когда вы передаете что-то свободной функции в качестве параметра, вместо того, чтобы функция вызывала другую функцию для получения информации, вы в основном делаете одно и то же: инверсия управления.Python также позволяет обрабатывать модули аналогично классам разными способами (конечно, больше, чем в Java и C #).Есть проблемы, которые могут быть решены путем передачи модулей в качестве параметров в функции.:)

До сих пор я думаю, что могу покрывать фабрики, синглтоны, объекты с несколькими экземплярами, просто используя Globals.

Синглтоны - плохой запах, если что-нибудь.Практически в каждом случае, по моему обширному опыту, они существуют, потому что кто-то думал, что было бы плохо (TM) в принципе иметь глобальный, не задумываясь о возможных вариантах, или почему они хотели такого рода доступ к одному общему объектуили даже почему глобальные «изначально плохие (TM)».

Вы могли бы создать глобальную функцию в Python, которая действует как фабрика.Тем не менее, я бы сказал, что Pythonic делает что-то из следующего:

a) во-первых, сделайте действительно, действительно, действительно убедитесь, что вы не можете просто делать то, что хотите с __init__.Я имею в виду, что в динамически типизированном языке вы можете таким образом много чего сделать.

b) Если __init__ его не обрезает, попробуйте использовать __new__ для управления поведением.

В Python классы сами являются объектами, которые можно вызывать.По умолчанию их вызов создает экземпляр класса.С помощью __new__ вы можете подключиться к этому.

c) Использовать декоратор, примененный к классу.Вот пример, который делает Singleton (только потому что):

def _singleton(cls):
  instance = cls()
  result = lambda: instance
  result.__doc__ = cls.__doc__
  return result

@_singleton
class example(object): pass

Способ, которым это работает: когда вы декорируете класс, вызывается _singleton() с передачей класса. Создается экземпляри кэшируется, и _singleton() возвращает анонимную функцию, которая будет возвращать экземпляр при вызове.Чтобы закончить шараду, документация класса прикреплена к анонимной функции.Затем Python связывает имя класса в глобальной области видимости с возвращенной анонимной функцией.Поэтому, когда вы вызываете его, вы каждый раз получаете один и тот же экземпляр класса.

Теперь, конечно, это все еще можно обойти (вы можете сделать что-то вроде example().__class__(), чтобы получить другой экземпляр),но гораздо яснее, что вы делаете что-то не так, чем если бы вы просто игнорировали фабричную функцию, чтобы нормально использовать конструктор.Кроме того, это означает, что вызывающий код фактически действует так, как если бы он вызывал конструктор в обычном режиме:)

Duck Typing - это то, что меня сейчас привлекает, поэтому он используется для определения интерфейсов, а затем базирования классовна этих интерфейсах и позволяя статическим вещам покрывать мою глупость, которую я чувствую, что без статической типизации контейнеры немного бесполезны.

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

7 голосов
/ 30 июля 2011

Заключение

(Следующее является наиболее релевантной частью оригинального поста. Я признаю, я немного поэтично, и поэтому я, хотя я должен просто включить наиболее важные предложения в их собственный раздел. Тем не менее, я чувствую, что поэтический Воск достаточно важен, чтобы я не удалил его.)

Впрыск зависимости все еще используется. Всегда будет необходимость взаимодействия объектов с уже созданными объектами. Потребуется, чтобы «родительские» объекты (или контейнеры, или что-то еще) устанавливали состояние своих «потомков». Их нужно будет передать через какой-то метод или установить через какое-то присваивание, но в абстрактном смысле это одно и то же.

Оригинальный ответ:

Тип системы

Python во многих отношениях является вторым наиболее математически чистым языком, с которым я когда-либо сталкивался - он следует только Схеме (хотя я никогда не использовал Haskell, я понимаю, что он тоже там).

Python изначально поддерживает замыкания, имеет продолжения (выходной синтаксис), множественное наследование и синтаксис понимания цикла, который в значительной степени не имеет аналогов. Все это приближает его к первоначальному видению Алонзо Черча в «Лямбда-исчислении» (первоначальные идеи Маккарти, стоящие за Лиспом). Python 3 делает его еще более чистым благодаря множеству представлений (которые заставляют мое сердце трепетать, просто думая об их врожденной красоте).

Постоянно и постоянно существует идея, что данные, хранящиеся в переменных Python, имеют больше общего со своими аналогами в математике, настолько, что интерфейс объекта можно просто уменьшить, - прилагательные или набор прилагательные, которые описывают объект ". По сути, интерфейс объекта целиком и полностью содержится в его __dict__ и отображается с dir.

Учитывая все вышесказанное, возникает вопрос: а может ли «традиционный» взгляд на вещи («традиционный» с кавычками, потому что Python столь же стар, как Java) действительно может работать на таком языке? Когда даже списки аргументов в Python имеют чувство ООП (kwargs, кто-нибудь?), Это действительно переворачивает мир с ног на голову.

Впрыск зависимости все еще используется. Всегда будет необходимость взаимодействия объектов с уже созданными объектами. Потребуется, чтобы «родительские» объекты (или контейнеры, или что-то еще) устанавливали состояние своих «потомков». Их нужно будет передать через какой-то метод или установить через какое-то присваивание, но в абстрактном смысле это одно и то же. Но есть неявное доверие, что содержимое переданного объекта __dict__ будет содержать соответствующее описание. Из-за этого становится намного меньше, «как только я создаю экземпляр этого объекта, я буду даровать ему все, что нужно для жизни», и гораздо больше: «Ну, да, объект нуждается в состоянии, поэтому я дать ему один. "

И это раскрывает скрытый аспект статической типизации. Чтобы нечто, ожидающее, что IFoo сработало, должно иметь полное и полное знание того, что значит быть IFoo, даже если ему никогда не понадобится 90% этого определения. Между тем, типизирование утки позволяет зависимому объекту знать только то, что свойства X, Y и Z должны присутствовать во время выполнения.

Глобал

Что касается глобалов. Избегайте их, если у вас нет другого выбора. Вам лучше использовать Singleton хотя бы потому, что Singletons позволяют вам регистрировать изменения значения. Это не относится к глобалам.

Существует правило программирования: чем сложнее и сложнее ваш интерфейс, тем сложнее его поддерживать. Если что-то помещено в глобальную переменную, что-нибудь в этом модуле и, возможно, что-нибудь в ANY модуль может изменить значение. Код может стать почти недетерминированным. Уверяю вас, печаль следует.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...