Python可以无缝地执行DI而不依赖于服务定位器吗?

sel*_*lf. 6 python dependency-injection

我来自C#世界,所以我的观点可能有些偏差.我想在Python中做DI,但是我注意到了一个趋势,它们都看起来依赖于服务定位器.也就是说,您必须将对象创建绑定到框架,例如injectlib.build(MyClass)为了获取实例MyClass.

这是我的意思的一个例子 -

from injector import Injector, inject


class Inner(object):
    def __init__(self):
        self.foo = 'foo'


class Outer(object):
    @inject(inner=Inner)
    def __init__(self, inner=None):
        if inner is None:
            print('inner not provided')
            self.inner = Inner()
        else:
            print('inner provided')
            self.inner = inner


injector = Injector()

outer = Outer()
print(outer.inner.foo)

outer = injector.get(Outer)
print(outer.inner.foo)
Run Code Online (Sandbox Code Playgroud)

有没有办法在Python中创建一个类,同时根据参数名称自动推断依赖类型?因此,如果我有一个被调用的构造函数参数my_class,那么MyClass将注入一个实例.我问的原因是我没有看到如何将依赖注入到通过第三方库自动创建的类中.

R P*_*gna 7

要回答你明确提出的问题:不,Python中没有内置的方法可以从名为my_class的参数中自动获取MyClass对象.

也就是说,既没有"将你的对象创建绑定到框架"也没有你给出的示例代码看起来非常Pythonic,这个问题总体上有点令人困惑,因为动态语言中的DI并不是什么大问题.

关于Python中DI的一般想法我会说这个演示文稿给出了很好的不同方法的概述.对于您的具体问题,我会根据您的尝试提供两种选择.

如果您正在尝试将DI添加到您自己的类中,我将在构造函数中使用具有默认值的参数,如该演示文稿所示.例如:

import time

class Example(object):
    def __init__(self, sleep_func=time.sleep):
        self.sleep_func = sleep_func

    def foo(self):
        self.sleep_func(10)
        print('Done!')
Run Code Online (Sandbox Code Playgroud)

然后你可以传入一个虚拟睡眠功能进行测试或其他什么.

如果你试图通过DI操纵库的类,(不是我真的可以想象一个用例,但看起来像你要问的那样)那么我可能只是修补那些类来改变任何需要改变的东西.例如:

import test_module

def dummy_sleep(*args, **kwargs):
    pass

test_module.time.sleep = dummy_sleep
e = test_module.Example()
e.foo()
Run Code Online (Sandbox Code Playgroud)