py2/py3k的简单而强大的python依赖注入
mainline的Python项目详细描述
简单而强大的python依赖注入。
- 文件:http://mainline.readthedocs.org/en/latest
- api文档:http://mainline.readthedocs.org/en/latest/mainline.html
- PYPI:https://pypi.python.org/pypi/mainline
为什么
纯python,所以它基本上可以在任何地方工作。 对cpython3.5,3.6,3.7以及2.7进行了测试。 pypy/pypy3也完全受支持。
只有外部依赖项是six和wrapt,这两个都是您可能已经拥有的。
支持在python3.x中使用函数注释。 这是对3.x和2.7都有效的标准语法的补充。
您的方法签名被完全保留,保持了内省能力。 (当然减去任何注入的参数。)
作用域是完全可配置的(每个可注入的),使您能够严格控制对象应该在哪里共享以及不应该在哪里共享。
支持“自动注入”,其中参数名用于确定注入的内容。 它也是完全可选的,因为它的动态特性使得性能稍差。
提供程序键通常是字符串,但实际上任何哈希对象都受支持,因此如果您喜欢使用类,请使用它。
请记住,在python中不能使用类作为参数名(这是正确的)。 例如,这意味着您不能自动注入它。 不过,您可以简单地创建一个别名来获得两个世界。世界就是你的牡蛎。
看看那个漂亮的注射器。
安装
pip install mainline
快速启动
确保检查文档以获取更多用例!
""" Initialize your Di instance. """>>>frommainlineimportDi>>>di=Di()""" Feed it your delicious factories, optionally scoped. """>>>@di.register_factory('apple')...defapple():...return'apple'""" Factories can of course be injected themselves. """>>>@di.f('banana',scope='global')# f is syntactic sugar for register_factory...defbanana():...return'banana'""" Let's verify that our factories above do what they're supposed to. """>>>di.resolve('apple')=='apple'anddi.resolve('banana')=='banana'True""" Positional arguments are injected in the order given: """>>>@di.inject('apple')...definjected(apple):...returnapple>>>injected()==apple()# verifyTrue""" Injecting keyword arguments is straight forward, you simply hand them as keyword arguments: """>>>@di.f('orange')# alias for register_factory...@di.i('apple')# alias for inject...deforange(apple):...return'banana',apple>>>@di.i('apple',an_orange='orange')...definjected(apple,arg1,an_orange=None):...returnapple,arg1,an_orange>>>injected('arg1')==(apple(),'arg1',orange())# verifyTrue""" Arguments that are not injected work as expected: """>>>@di.inject('apple')...definjected(apple,arg1):...returnapple,arg1>>>injected('arg1')==(apple(),'arg1')True""" Injection on a class injects upon it's `__init__` method: """>>>@di.inject('apple')...classInjectee(object):...def__init__(self,apple):...self.apple=apple>>>Injectee().apple==apple()True""" You can inject class-level properties using `di.inject_classproperty()`: """>>>@di.inject_classproperty('apple')...classInjectee(object):...pass>>>Injectee.apple==apple()True""" Injecting providers based upon the argpsec can be done with `di.auto_inject`, or it's shortened alias `di.ai()`: """>>>@di.auto_inject()...definjected(apple):...returnapple>>>injected()==apple()True>>>@di.ai('apple')# alias for auto_inject...definjected(apple,arg1):...returnapple,arg1>>>injected('arg1')==(apple(),'arg1')True>>>@di.auto_inject()...definjected(apple,arg1,banana=None):...returnapple,arg1,banana>>>injected('arg1')==(apple(),'arg1',banana())True>>>@di.auto_inject(renamed_banana='banana')...definjected(apple,arg1,renamed_banana):...returnapple,arg1,renamed_banana>>>injected('arg1')==(apple(),'arg1',banana())True
运行测试
tox用于测试多个python版本。
tox