web-dev-qa-db-fra.com

Cadre d'injection de dépendance Python

Existe-t-il un cadre équivalent à Guice ( http://code.google.com/p/google-guice ) pour Python?

44
Mark Roddy

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

13
Matthew Trevor

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:

  • Inversion Of Control (injection de dépendance) - utilisez soit le format XML classique, soit le décorateur python @Object (similaire au sous-projet Spring JavaConfig) pour relier des éléments. Bien que le format @Object ne soit pas identique au style Guice (câblage centralisé ou informations de câblage dans chaque classe), il constitue un moyen précieux de câbler votre application python.
  • Programmation orientée aspect - applique des intercepteurs dans un paradigme de programmation horizontale (au lieu d'un héritage vertical OOP) pour des opérations telles que les transactions, la sécurité et la mise en cache.
  • DatabaseTemplate - La lecture de la base de données nécessite un cycle monotone d'ouverture de curseurs, de lecture de lignes et de fermeture de curseurs, ainsi que de gestionnaires d'exceptions. Avec cette classe de modèle, tout ce dont vous avez besoin est la fonction de requête SQL et de gestion des lignes. Spring Python fait le reste.
  • Transactions de base de données - L'emballage de plusieurs appels de base de données avec des transactions peut rendre votre code difficile à lire. Ce module propose plusieurs manières de définir des transactions sans compliquer les choses.
  • Sécurité - Des intercepteurs de sécurité plug-in pour verrouiller l'accès à vos méthodes, en utilisant à la fois l'authentification et l'autorisation de domaine.
  • Remoting - Il est facile de convertir votre application locale en une application distribuée. Si vous avez déjà créé vos composants client et serveur à l'aide du conteneur IoC, le passage de local à distribué ne constitue qu'un changement de configuration.
  • Exemples - pour vous aider à illustrer diverses fonctionnalités de Spring Python, des exemples d’applications ont été créés:
    • PetClinic - L'exemple d'application Web de Spring Framework a été entièrement reconstruit à l'aide de conteneurs Web en python, notamment: CherryPy . Allez voir un exemple d'utilisation de ce cadre. (REMARQUE: d'autres frameworks Web python seront ajoutés à cette liste à l'avenir).
    • Spring Wiki - Les wikis sont un moyen puissant de stocker et de gérer du contenu, nous avons donc créé un logiciel simple comme démonstration!
    • Spring Bot - Utilisez Spring Python pour créer un minuscule bot permettant de gérer le canal IRC de votre projet open source.
25
gregturn

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é.

14
Mikhail Holovaty

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).

9
user35818

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.

7
phss
6

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.

3
Y.H Wong

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.

2
Skilldrick

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

1
Roman Mogylatov

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/

1
chiborg

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

0
BillMartus

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()

https://pypi.python.org/pypi/py3njection

0
Aigrefin

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.

0
Rodrigo Martins

Il y a dyject ( http://dyject.com ), un framework léger pour Python 2 et Python 3 qui utilise le ConfigParser intégré

0
djsumdog

J'ai récemment publié une micro bibliothèque soignée (IMHO) pour DI en python:

https://github.com/suned/serum

0