Pythondependency injection框架
是否有与Guice( http://code.google.com/p/google-guice )for Python相同的框架?
我没有使用它,但Spring Python框架基于Spring并实现了Inversion of Control 。
Python项目中也出现了Guice: snake-guice
Spring Python是基于Java的Spring Framework和Spring Security的一个分支,针对Python。 该项目目前包含以下function:
- 控制反转(dependency injection) – 使用经典的XML或python @Object装饰器(类似于Spring JavaConfig子项目)将任何东西连接在一起。 虽然@Object格式与Guice风格不同(每个类中集中布线与布线信息),但它是连接python应用程序的有效方法。
- 面向方面的编程 – 在事务,安全和caching等事物中,在水平编程范例中应用拦截器(而不是垂直的OOPinheritance)。
- DatabaseTemplate – 从数据库读取需要打开游标,读取行和closures游标以及exception处理程序的单调循环。 使用这个模板类,您只需要SQL查询和行处理函数。 其余的是Python。
- 数据库事务 – 使用事务包装多个数据库调用会使您的代码难以阅读。 该模块提供多种方式来定义事务,而不会使事情变得复杂。
- 安全性 – 插件安全拦截器可以使用身份validation和域授权来locking对方法的访问。
- 远程处理 – 将本地应用程序转换为分布式应用程序非常简单。 如果您已经使用IoC容器构build了客户端和服务器部分,则从本地到分布式只是configuration更改。
- 示例 – 为了演示Spring Python的各种function,已经创build了一些示例应用程序:
- PetClinic – Spring框架的示例web应用程序已经从python web容器包括CherryPy从头开始重build。 去看看如何使用这个框架的例子。 (注:其他python web框架将在未来添加到此列表中)。
- 维基 – 维基是存储和pipe理内容的强大方式,所以我们创build了一个简单的演示!
- Spring Bot – 使用Spring Python构build一个小型的机器人来pipe理开源项目的IRC频道。
我喜欢这个简单而整洁的框架。
http://pypi.python.org/pypi/injector/
dependency injection作为一种forms模式在Python中比其他语言中的有用性更低,主要是因为它支持关键字参数,对象可以轻松地被模拟,以及它的dynamic特性。
也就是说,协助这个过程的框架可以从大型应用程序中删除大量的锅炉板。 这是注射器可以帮助的地方。 它会自动和传递地提供关键字参数和它们的值。 作为一个额外的好处,喷油器通过使用模块s鼓励很好的分隔代码。
虽然受到Guice的启发,但它并没有狂妄地复制它的API。 提供Pythonic API胜过忠诚。
作为monkeypatching的替代品,我喜欢DI。 像http://code.google.com/p/snake-guice/这样的新兴项目可能适合这个账单。;
Dennis Kempin(08年8月) 在Python中查看博客文章Dependency Injection 。
除此之外:
- Zope组件架构
- pyContainer
pinject( https://github.com/google/pinject )是一个较新的select。 它似乎由Google维护,并遵循与Guice相似的模式( https://code.google.com/p/google-guice/ ),它是Java的对应模式。
有一个Guicey python注入项目。 这是相当活跃的,很less的代码,然后Spring-python,但是,我还没有find一个理由使用它。
如果你只是想在Python中进行dependency injection,你不需要一个框架。 看看dependency injection的Python方法 。 这真的很简单,只有c。 50行代码。
下面是一个dependency injection容器的小例子,它根据构造函数的参数名进行构造函数注入:
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 injection器现在有点不同了。 最好从Dependency Injector GitHub页面开始获取实际示例 – https://github.com/ets-labs/python-dependency-injector
我做了一个库来做到这一点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\'ma example of %s' % name) logger.debug('I\'m finishing...') call(main)
并使用来自python3的types提示
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\'ma example of %s' % name) logger.debug('I\'m finishing...') call(main)
如果你喜欢一个非常小的解决scheme有一个小function,它只是一个依赖设置。
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()