gpt4 book ai didi

python - 如何做依赖注入(inject)python-way?

转载 作者:太空狗 更新时间:2023-10-29 17:45:39 25 4
gpt4 key购买 nike

我最近阅读了很多关于 python-way 的文章,所以我的问题是

How to do dependency injection python-way?

我说的是通常情况,例如,服务 A 需要访问 UserService 以进行授权检查。

最佳答案

这要视情况而定。例如,如果您将依赖注入(inject)用于测试目的——这样您就可以轻松地模拟出一些东西——您通常可以完全放弃注入(inject):您可以模拟出您将注入(inject)的模块或类:

subprocess.Popen = some_mock_Popen
result = subprocess.call(...)
assert some_mock_popen.result == result

subprocess.call() 将调用 subprocess.Popen(),我们可以模拟它而无需以特殊方式注入(inject)依赖项。我们可以直接替换subprocess.Popen。 (这只是一个示例;在现实生活中,您会以更稳健的方式执行此操作。)

如果你在更复杂的情况下使用依赖注入(inject),或者当模拟整个模块或类不合适时(因为,例如,你只想模拟一个特定的调用)然后使用类属性或模块全局变量作为依赖项是通常的选择。例如,考虑一个 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 类),它现在可以工作,但如果对象在question 更改为正常的 future future,它会令人困惑。

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

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(...)

当像这样设置实例属性时,您永远不必担心描述符会触发,因此只需分配函数(或类或其他可调用对象或实例)就可以了。

关于python - 如何做依赖注入(inject)python-way?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2722501/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com