受guice启发的注入器python依赖注入框架

injector的Python项目详细描述


imageCoverage Status

简介

依赖注入作为一种形式模式在python中不如 在其他语言中,主要是因为它支持关键字参数, 对象被模仿的容易程度及其动态特性。

也就是说,一个协助这个过程的框架可以消除很多 更大用途的锅炉板。这是注射器可以帮助的地方。 它自动且可传递地提供关键字参数 价值观。作为一个额外的好处,注入器可以很好地鼓励 通过使用Modules来划分代码。

虽然受到guice的启发,但它并没有盲目地复制自己的api。 提供一个Python般的api胜过忠诚。

如何得到注射器?

injector与cpython 3.5+和pypy3一起实现python3.5+。

一个简单的例子

>>>frominjectorimportInjector,inject>>>classInner:...def__init__(self):...self.forty_two=42...>>>classOuter:...@inject...def__init__(self,inner:Inner):...self.inner=inner...>>>injector=Injector()>>>outer=injector.get(Outer)>>>outer.inner.forty_two42

如果您愿意,也可以使用dataclasses

fromdataclassesimportdataclassfrominjectorimportInjector,injectclassInner:def__init__(self):self.forty_two=42@inject@dataclassclassOuter:inner:Innerinjector=Injector()outer=injector.get(Outer)print(outer.inner.forty_two)# Prints 42

完整示例

下面是一个完整的示例,让您了解喷油器的工作原理:

>>>frominjectorimportModule,Key,provider,Injector,inject,singleton

我们将使用内存中的sqlite数据库作为示例:

>>>importsqlite3

并构造一个虚构的RequestHandler类,该类使用sqlite 连接:

>>>classRequestHandler:...@inject...def__init__(self,db:sqlite3.Connection):...self._db=db......defget(self):...cursor=self._db.cursor()...cursor.execute('SELECT key, value FROM data ORDER by key')...returncursor.fetchall()

接下来,为了示例起见,我们将创建一个配置类型:

>>>classConfiguration:...def__init__(self,connection_string):...self.connection_string=connection_string

接下来,我们使用模块将配置绑定到喷油器:

>>>defconfigure_for_testing(binder):...configuration=Configuration(':memory:')...binder.bind(Configuration,to=configuration,scope=singleton)

接下来我们创建一个初始化数据库的模块。这取决于 上述模块提供的用于创建新数据库的配置 连接,然后用一些虚拟数据填充它,并提供 Connection对象:

>>>classDatabaseModule(Module):...@singleton...@provider...defprovide_sqlite_connection(self,configuration:Configuration)->sqlite3.Connection:...conn=sqlite3.connect(configuration.connection_string)...cursor=conn.cursor()...cursor.execute('CREATE TABLE IF NOT EXISTS data (key PRIMARY KEY, value)')...cursor.execute('INSERT OR REPLACE INTO data VALUES ("hello", "world")')...returnconn

(注意我们如何将配置与数据库分离 初始化代码。)

最后,我们初始化一个Injector,并使用它来实例化 RequestHandler实例。第一个可传递的构造 sqlite3.Connection对象,以及 依次需要,然后实例化我们的RequestHandler

>>>injector=Injector([configure_for_testing,DatabaseModule()])>>>handler=injector.get(RequestHandler)>>>tuple(map(str,handler.get()[0]))# py3/py2 compatibility hack('hello','world')

我们还可以验证我们的ConfigurationSQLite连接 喷油器内是否确实存在单重态:

>>>injector.get(Configuration)isinjector.get(Configuration)True>>>injector.get(sqlite3.Connection)isinjector.get(sqlite3.Connection)True

你可能会想:“这是一项庞大的工作 只是给我一个数据库连接“,你是对的;依赖 对于较小的项目,注入通常没有那么有用。它来了 在大型项目中投入自己的前期工作 有两种方式:

  1. 迫使脱钩。在我们的例子中,这通过解耦来说明 我们的配置和数据库配置。
  2. 配置类型后,可以在任何位置注入 额外的努力。只要@inject,它就会出现。我们不是真的 在这里举例说明,但是你可以想象添加任意数字 所有子类都将自动 提供数据库连接。

脚注

这个框架类似于snake guice,但目的是简化。

版权所有2010-2013归Alec Thomas所有,根据BSD许可证

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java如何设置将在类声明中使用的输入参数?   混合表达式和文本的java SpEL模板   getHeaders()无法返回java Mockito测试SimpMessageHeaderAccessor getHeaders()应返回MessageHeaders   如何在java中创建循环回菜单的方法   具有多态性的Java列表问题   java Guice多数据库自动切换   java服务器错误,状态代码:400,错误代码:100005,消息:您已超过组织的内存限制   静态mutator方法的Java命名约定   用于实例化另一个java文件的groovy java代码   javajavax。网ssl。SSLHandshakeException:握手期间远程主机关闭连接。重新启动服务器后,它工作正常,但会再次显示   java WebSphere+RAD+Taglib   REST客户端中出现java异常:找不到contenttype application/json的messagebodyreader   无参数setter的Java命名   java从数组中删除重复字符