如何做依赖注入python方式?

前端之家收集整理的这篇文章主要介绍了如何做依赖注入python方式?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我最近一直在阅读很多关于 python的方式,所以我的问题是

How to do dependency injection python-way?

我正在谈论通常的情况,例如,服务A需要访问UserService进行授权检查.

这一切都取决于情况.例如,如果您使用依赖注入来进行测试,所以您可以轻松地嘲笑某些内容 – 您可以经常放弃注入:您可以嘲笑您将注入的模块或类:
subprocess.Popen = some_mock_Popen
result = subprocess.call(...)
assert some_mock_popen.result == result

subprocess.call()将调用subprocess.Popen(),我们可以模拟它,而不必以特殊的方式注入依赖.我们可以直接替换subprocess.Popen. (这只是一个例子;在现实生活中,你会以更加健壮的方式做到这一点)

如果对更复杂的情况使用依赖注入,或者模拟整个模块或类不适用(因为例如,您只想嘲弄一个特定的调用),则使用类属性或模块全局变量作为依赖项是通常的选择.例如,考虑到一个my_subprocess.py:

from subprocess import Popen

def my_call(...):
    return Popen(...).communicate()

您只能通过分配给my_subprocess.Popen来轻松替换由my_call()创建的Popen调用;它不会影响任何其他调用subprocess.Popen(但它会替换所有调用my_subprocess.Popen,当然).类似地,类属性

class MyClass(object):
    Popen = staticmethod(subprocess.Popen)
    def call(self):
        return self.Popen(...).communicate(...)

当使用这样的类属性时,考虑到这些选项很少需要,你应该注意使用staticmethod.如果不这样做,并且您插入的对象是一个正常的函数对象或另一种类型的描述符,就像一个属性,在从类或实例中检索到时,会执行一些特殊的描述,它会做错事.更糟糕的是,如果你现在使用的东西不是一个描述符(比如subprocess.Popen类,在这个例子中),它现在就可以工作,但是如果有问题的对象改变了一个正常的功能,那么它将会令人困惑.

最后,只有简单的回调;如果您只想将特定实例的类绑定到特定的服务,则可以将服务(或一项或多项服务的方法)传递给类初始化程序,并使用它:

class MyClass(object):
    def __init__(self,authenticate=None,authorize=None):
        if authenticate is None:
            authenticate = default_authenticate
        if authorize is None:
            authorize = default_authorize
        self.authenticate = authenticate
        self.authorize = authorize
    def request(self,user,password,action):
        self.authenticate(user,password)
        self.authorize(user,action)
        self._do_request(action)

...
helper = AuthService(...)
# Pass bound methods to helper.authenticate and helper.authorize to MyClass.
inst = MyClass(authenticate=helper.authenticate,authorize=helper.authorize)
inst.request(...)

当设置这样的实例属性时,您不必担心描述符触发,所以只需分配函数(或类或其他可调用或实例)即可.

猜你在找的设计模式相关文章