透明依赖注入。
antidote的Python项目详细描述
Antodotes是Python3.5的声明性依赖注入微框架+ 它尝试执行以下操作:
- 可以很容易地应用于任何现有代码。
- 找到依赖项的源和用法很简单(通过 IDE的“转到定义/查找用法”)。
- 限制喷射对性能的影响。
为什么?
简而言之,解毒剂避免了实例化和管理 服务。你按照它们的定义来声明它们,然后把它们注入任何地方 需要与简单的装饰,其中 不要更改与对象的交互方式。单元测试不是 影响,因为可以覆盖任何注入并控制可用的 容易依赖。
功能突出显示
核心功能:
- 通过类型提示和参数名和/或(可选)执行的注入 具有显式指定的依赖项。
- 依赖循环检测
- 螺纹安全和有限的性能冲击(见 injection benchmark)。
- 通过依赖提供程序,易于扩展。所有后续依赖项都是 用它来实现。
依赖关系:
- 服务和工厂:提供类的实例。
- 标记:可以标记依赖项,因此所有匹配特定标记的依赖项都可以 恢复。
- 配置:延迟计算的常数。
- 延迟函数调用:延迟提供函数调用的结果。
安装
要安装解毒剂,只需运行以下命令:
pip install antidote
快速启动
下面是一个试图展示解毒剂大部分特性的示例:
""" Simple example where a MovieDB interface is defined which can be used to retrieve the best movies. In our case the implementation uses IMDB to dot it. """fromfunctoolsimportreduceimportantidoteclassMovieDB:defget_best_movies(self):passclassImdbAPI:""" Class from an external library. """def__init__(self,*args,**kwargs):""" Initializes the IMDB API. """# Usage of constants for configuration makes refactoring easier and is# less error-prone. Moreover Conf will only be instantiated if necessary.classConf(metaclass=antidote.LazyConstantsMeta):IMDB_HOST='imdb.host'IMDB_API_KEY='imdb.api_key'def__init__(self):# Load configuration from somewhereself._raw_conf={'imdb':{'host':'dummy_host','api_key':'dummy_api_key'}}defget(self,key):""" 'a.b' -> self._raw_conf['a']['b'] """returnreduce(dict.get,key.split('.'),self._raw_conf)# Declare a factory which should be called to instantiate Database.# The order of the arguments is here used to map the dependencies.# A dictionary mapping arguments name to their dependency could also# have been used.@antidote.factory(dependencies=(Conf.IMDB_HOST,Conf.IMDB_API_KEY))defimdb_factory(host:str,api_key:str)->ImdbAPI:""" Configure your database. """returnImdbAPI(host=host,api_key=api_key)# implements specifies that IMDBMovieDB should be used whenever MovieDB is requested.@antidote.implements(MovieDB)# Registering IMDBMovieDB makes it available in Antidote. (required for @implements)@antidote.registerclassIMDBMovieDB(MovieDB):# Dependencies of __init__() are injected by default when# registering a service.# Note that IMDBMovieDB does not build itself ImdbAPI, which makes testing# easier.def__init__(self,imdb_api:ImdbAPI):self._imdb_api=imdb_apidefget_best_movies(self):pass# Inject dependencies in f(), by default only type annotations are used. But# arguments name, explicit mapping, etc.. can also be used.@antidote.injectdeff(movie_db:MovieDB):""" Do something with your database. """# Can be called without arguments now.f()assertantidote.world.get(MovieDB)isantidote.world.get(IMDBMovieDB)# You can still explicitly pass the arguments to override# injection.conf=Conf()f(IMDBMovieDB(imdb_factory(# equivalent to conf._raw_conf['db.host'], mainly to make your tests easier.host=conf.IMDB_HOST,api_key=conf._raw_conf['imdb']['api_key'],)))
错误报告/功能请求
欢迎任何反馈,随时提交问题和改进 请求!:) 对于任何问题,请在github上打开一个问题。
如何贡献
- 检查是否有未解决的问题或打开新的问题以围绕 特征或缺陷。
- 在github上进行回购。运行测试以确认它们都通过了 机器。如果找不到失败的原因,请打开一个问题。
- 开始对主分支进行更改。
- 编写显示代码按预期工作的测试。(这也是 意味着100%的覆盖率。)
- 发送拉取请求。
在发出拉取请求之前,请确保从“上游”合并最新的!
拉取请求应避免到:
- <> LI>使解毒剂融入现有代码更加困难。
- 打破向后兼容。
- 为ide创建难以理解的特性,例如 字符串dependency id以某种方式指向非单例对象。用户可以 但解毒剂不应该这样。
如果:
- 类和非平凡函数没有文档字符串来记录它们 行为。
- 测试不包括所有代码更改。
请毫不犹豫地发送拉取请求,即使请求不完整,也可以提前到达 反馈!:)