2014-10-07 48 views
6

我来自C#世界,所以我的看法可能有点偏斜。我期待在Python中使用DI,但是我注意到了一个图书馆的趋势,他们似乎都依赖于服务定位器。也就是说,您必须将您的对象创建与框架绑定,例如injectlib.build(MyClass)才能获得MyClass的实例。Python无需依赖服务定位器就可以完成DI吗?

这里是我的意思的例子 -

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的实例。我想问的原因是我没有看到如何将依赖注入到通过第三方库自动创建的类中。

回答

6

要回答您明确提出的问题:no,Python中没有内置的方法来自动从名为my_class的参数获取MyClass对象。这就是说,既没有将你的对象创建绑定到框架上,也没有提供给你的示例代码看起来非常糟糕,这个问题总的来说有点令人困惑,因为动态语言中的DI并不是什么大不了的事情。

关于Python中关于DI的一般想法我会说this presentation给出了对不同方法的很好的概述。对于你的具体问题,我会根据你可能要做的事情给出两个选项。

如果您想将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!') 

然后,你可以传递一个虚拟睡眠函数进行测试或其他。

如果你想通过DI,(不是我可以真正想象的用例,但看起来像你问的东西)操作图书馆的类,那么我可能会猴子修补这些类到改变需要改变的东西。例如:

import test_module 

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

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

很好的答案!在过去的几个月里,我一直在稳步地做Python,而不是像我从哪里来(C#)那样,Python确实不需要DI。事实上,我讨厌混合两者。 – 2015-07-20 12:16:18

相关问题