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

时间:2014-10-07 18:44:18

标签: 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)

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

1 个答案:

答案 0 :(得分:7)

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

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

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

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

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!')

然后你可以通过虚拟睡眠功能进行测试或其他任何事情。

如果你试图通过DI来操纵图书馆的课程,(不是我真正想象的一个用例,但看起来就像你在做什么问)那么我可能只是修补那些类来改变任何需要改变的东西。 E.g:

import test_module

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

test_module.time.sleep = dummy_sleep
e = test_module.Example()
e.foo()