В Python есть контейнер для инъекций зависимости?

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

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

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

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

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

изменить

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

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

Ответы

Ответ 1

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

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

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

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

Я сомневаюсь, но тогда я никогда не видел их в С# или Java. На мой взгляд, инъекция зависимостей - это технология . И там действительно не так уж и много.

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

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

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

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

Вы могли сделать глобальную функцию в Python, которая действует как factory. Однако я бы сказал, что более 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() возвращает анонимную функцию, которая возвращает экземпляр при вызове. Для завершения charade документация класса прикрепляется к анонимной функции. Затем Python перенаправляет имя класса в глобальной области на возвращаемую анонимную функцию. Поэтому, когда вы вызываете его, каждый раз вы получаете один и тот же экземпляр класса.

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

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

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

Ответ 2

Заключение

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

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

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

Системы типов

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

Python поддерживает блокировки изначально, имеет продолжения (синтаксис вывода), множественное наследование и синтаксис понимания цикла, который в значительной степени не имеет аналогов. Все это приближает его к оригинальному видению Церкви Алонсо в Lambda Calculus (оригинальные идеи Маккарти за Lisp). Python 3 делает его еще более чистым с множеством понятий (которые заставляют мое сердце трепетать, просто думая о своей неотъемлемой красоте).

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

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

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

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

Globals

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

Существует правило программирования, чем более открытый и сложный интерфейс, тем сложнее его поддерживать. Если что-то помещено в глобальную переменную, что-либо в этом модуле и, возможно, что-либо в модуле ЛЮБОЙ, может изменить значение. Код может почти стать недетерминированным. Уверяю вас, следует печаль.