Ответ 1
Я не использовал его, но Spring Python основывается на Spring и реализует Inversion of Control.
Также существует проект Guice in Python: snake-guice
Существует ли структура, эквивалентная Guice (http://code.google.com/p/google-guice) для Python?
Я не использовал его, но Spring Python основывается на Spring и реализует Inversion of Control.
Также существует проект Guice in Python: snake-guice
Spring Python является ответвлением Java Spring Framework и Spring безопасности, предназначенной для Python. Этот проект в настоящее время содержит следующие функции:
Мне нравится эта простая и аккуратная структура.
http://pypi.python.org/pypi/injector/
Инъекция зависимостей как формальный шаблон менее полезна в Python, чем на других языках, в первую очередь из-за поддержки ключевого слова аргументы, легкость, с которой объекты могут быть издевались, и ее динамические природа.
Тем не менее, рамки для оказания помощи в этом процессе могут значительно сократить котельной плиты из более крупных применений. То, что инжектор может Помогите. Он автоматически и транзитивно предоставляет аргументы ключевых слов с их значениями. В качестве дополнительного преимущества Инжектор поощряет красиво разделенный код с помощью модуля s.
Будучи вдохновленным Гисом, он не рабски реплицирует свои API. Предоставление Pythonic API превосходит верность.
В качестве альтернативы monkeypatching мне нравится DI. Заложенный проект, такой как http://code.google.com/p/snake-guice/, может соответствовать счету.
Или см. сообщение в блоге Инъекция зависимостей в Python от Dennis Kempin (август '08).
Кроме того:
pinject (https://github.com/google/pinject) - более новая альтернатива. Он, похоже, поддерживается Google и следует аналогичной схеме для Guice (https://code.google.com/p/google-guice/), это Java-аналог.
Существует несколько проектов Guicey python-inject. Это довольно активно, и LOT меньше кода, чем Spring -python, но опять же, я еще не нашел причины использовать его.
Если вы просто хотите сделать инъекцию зависимостей в Python, вам не нужна фреймворк. Посмотрите Зависимость от инъекции Путь Python. Это очень быстро и просто, и только c. 50 строк кода.
Вот небольшой пример контейнера инъекций зависимостей, который выполняет инъекцию конструктора на основе имен аргументов конструктора:
http://code.activestate.com/recipes/576609-non-invasive-dependency-injection/
Оставлю мои 5 центов здесь:)
https://pypi.python.org/pypi/dependency_injector
"""Pythonic way for Dependency Injection."""
from dependency_injector import providers
from dependency_injector import injections
@providers.DelegatedCallable
def get_user_info(user_id):
"""Return user info."""
raise NotImplementedError()
@providers.Factory
@injections.inject(get_user_info=get_user_info)
class AuthComponent(object):
"""Some authentication component."""
def __init__(self, get_user_info):
"""Initializer."""
self.get_user_info = get_user_info
def authenticate_user(self, token):
"""Authenticate user by token."""
user_info = self.get_user_info(user_id=token + '1')
return user_info
print AuthComponent
print get_user_info
@providers.override(get_user_info)
@providers.DelegatedCallable
def get_user_info(user_id):
"""Return user info."""
return {'user_id': user_id}
print AuthComponent().authenticate_user(token='abc')
# {'user_id': 'abc1'}
ОБНОВЛЕНО
Некоторое время прошло, и инжектор зависимостей теперь немного отличается. Лучше начать с страницы Dependency Injector GitHub для получения фактических примеров - https://github.com/ets-labs/python-dependency-injector
Я сделал lib для этого https://github.com/ettoreleandrotognoli/python-cdi Надеюсь, что это поможет
Он доступен на pypi: https://pypi.python.org/pypi/pycdi
С его помощью вы можете делать инъекции с помощью python2
import logging
from logging import Logger
from pycdi import Inject, Singleton, Producer
from pycdi.shortcuts import call
@Producer(str, _context='app_name')
def get_app_name():
return 'PyCDI'
@Singleton(produce_type=Logger)
@Inject(app_name=str, _context='app_name')
def get_logger(app_name):
return logging.getLogger(app_name)
@Inject(name=(str, 'app_name'), logger=Logger)
def main(name, logger):
logger.info('I\'m starting...')
print('Hello World!!!\nI\'m a example of %s' % name)
logger.debug('I\'m finishing...')
call(main)
И используя подсказки типа из python3
import logging
from logging import Logger
from pycdi import Inject, Singleton, Producer
from pycdi.shortcuts import call
@Producer(_context='app_name')
def get_app_name() -> str:
return 'PyCDI'
@Singleton()
@Inject(logger_name='app_name')
def get_logger(logger_name: str) -> Logger:
return logging.getLogger(logger_name)
@Inject(name='app_name')
def main(name: str, logger: Logger):
logger.info('I\'m starting...')
print('Hello World!!!\nI\'m a example of %s' % name)
logger.debug('I\'m finishing...')
call(main)
Если вы предпочитаете действительно крошечное решение, там есть небольшая функция, это просто средство настройки зависимостей.
https://github.com/liuggio/Ultra-Lightweight-Dependency-Injector-Python
Здесь dyject (http://dyject.com), легкая структура как для Python 2, так и для Python 3, которая использует встроенный ConfigParser
Если вам нужен такой вид (новый новый, как они говорят), я недавно сделал что-то близкое в Python 3, которое наилучшим образом соответствовало моим простым потребностям для побочного проекта.
Все, что вам нужно, это @inject по методу (включая, конечно, __init__). Остальное делается через аннотации.
from py3njection import inject
from some_package import ClassToInject
class Demo:
@inject
def __init__(self, object_to_use: ClassToInject):
self.dependency = object_to_use
demo = Demo()