Existe-t-il un cadre équivalent à Guice ( http://code.google.com/p/google-guice ) pour Python?
Je ne l'ai pas utilisé, mais le framework Spring Python est basé sur Spring et implémente Inversion of Control .
Il semble également y avoir un projet Guice in Python: snake-guice
Spring Python est une émanation de Spring Framework et Spring Security basé sur Java et destinée à Python. Ce projet contient actuellement les fonctionnalités suivantes:
J'aime ce cadre simple et soigné.
http://pypi.python.org/pypi/injector/
L'injection de dépendance en tant que modèle formel est moins utile en Python que dans d'autres langues, principalement en raison de sa prise en charge du mot clé arguments, la facilité avec laquelle les objets peuvent être moqués, et sa dynamique la nature.
Cela dit, un cadre d’aide à ce processus peut éliminer beaucoup de choses de la plaque de la chaudière de plus grandes applications. C'est là que l'injecteur peut Aidez-moi. Il fournit automatiquement et transitoirement des arguments de mots clés avec leurs valeurs. Comme avantage supplémentaire, Injector encourage bien code compartimenté par l’utilisation de Module s.
Bien que inspiré par Guice, il ne reproduit pas servilement son API. Fournir une API Pythonic l'emporte sur la fidélité.
Comme alternative au monkeypatching, j'aime le DI. Un projet naissant tel que http://code.google.com/p/snake-guice/ pourrait faire l'affaire.
Ou consultez le blog Injection de dépendance en Python de Dennis Kempin (août 2008).
pinject ( https://github.com/google/pinject ) est une alternative plus récente. Il semble être maintenu par Google et suivre un schéma similaire à celui de Guice ( https://code.google.com/p/google-guice/ ), son équivalent en Java.
Par ailleurs:
Il y a un projet un peu Guicey python-inject . C'est assez actif, et BEAUCOUP moins de code que Spring-python, mais là encore, je n'ai pas encore trouvé de raison de l'utiliser.
Si vous voulez juste faire une injection de dépendance en Python, vous n'avez pas besoin d'un framework. Regardez Injection de dépendance à la manière de Python . C'est vraiment rapide et facile, et seulement c. 50 lignes de code.
Laisse mes 5 cents ici :)
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'}
MIS À JOUR
Un peu de temps a passé et Dependency Injector est un peu différent maintenant. Il est préférable de partir de la page Dependency Injector GitHub pour obtenir des exemples réels - https://github.com/ets-labs/python-dependency-injector
J'ai fait un lib pour faire cela https://github.com/ettoreleandrotognoli/python-cdi J'espère que cela aide
Il est disponible sur pypi: https://pypi.python.org/pypi/pycdi
Avec cela, vous pouvez faire des injections avec 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)
Et en utilisant les indications de type de 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)
Voici un petit exemple de conteneur d'injection de dépendance qui effectue une injection de constructeur en fonction des noms d'argument de constructeur:
http://code.activestate.com/recipes/576609-non-invasive-dependency-injection/
Si vous préférez une solution vraiment minuscule, il y a une petite fonction, c'est juste un indicateur de dépendance.
https://github.com/liuggio/Ultra-Lightweight-Dependency-Injector-Python
Si vous voulez un guice comme (le nouveau nouveau comme on dit), j'ai récemment créé quelque chose de proche en Python 3 qui répondait le mieux à mes besoins simples pour un projet parallèle.
Tout ce dont vous avez besoin est un @inject sur une méthode (__init__ inclus bien sûr) . Le reste est fait par des annotations.
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()
Le @autowired
décorator est plus simple qu'un framework.
Ce décorateur fournit une injection de dépendance propre et un support d’initialisation paresseux.
Cela tourne le code comme ceci:
def __init__(self, *, model: Model = None, service: Service = None):
if model is None:
model = Model()
if service is None:
service = Service()
self.model = model
self.service = service
# actual code
dans ceci:
@autowired
def __init__(self, *, model: Model, service: Service):
self.model = model
self.service = service
# actual code
Ce n'est pas un framework, donc il n'y a aucun workflow d'installation et d'application, bien qu'il ne fournisse pas de manipulation des contextes d'injection.
Divulgation: Je suis le responsable du projet.
Il y a dyject ( http://dyject.com ), un framework léger pour Python 2 et Python 3 qui utilise le ConfigParser intégré
J'ai récemment publié une micro bibliothèque soignée (IMHO) pour DI en python: