python依赖注入_如何用python方式进行依赖注入?

这要看情况而定。例如,如果将依赖项注入用于测试目的(因此可以很容易地模拟出某些内容),则通常可以完全放弃注入:相反,可以模拟出要注入的模块或类: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(...)

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值