Python依赖注入的方式是什么?

发布于 2021-01-29 18:35:16

介绍

对于Java,依赖注入作为纯OOP工作,即,您提供要实现的接口,并且在框架代码中接受实现已定义接口的类的实例。

现在,对于Python,您可以以相同的方式进行操作,但是对于Python,我认为该方法的开销太大。那么,您将如何以Pythonic的方式实现它呢?

用例

说这是框架代码:

class FrameworkClass():
    def __init__(self, ...):
        ...

    def do_the_job(self, ...):
        # some stuff
        # depending on some external function

基本方法

最幼稚(也许是最好的?)方法是要求将外部函数提供给FrameworkClass构造函数,然后从该do_the_job方法中调用它。

框架代码:

class FrameworkClass():
    def __init__(self, func):
        self.func = func

    def do_the_job(self, ...):
        # some stuff
        self.func(...)

客户代码:

def my_func():
    # my implementation

framework_instance = FrameworkClass(my_func)
framework_instance.do_the_job(...)

问题很简短。有没有更好的常用Pythonic方法来做到这一点?也许有任何支持这种功能的库?

更新:具体情况

想象一下,我开发了一个微型Web框架,该框架使用令牌处理身份验证。该框架需要一个功能,以提供ID从令牌中获取的一些令牌,并获取与之相对应的用户ID

显然,框架对用户或任何其他特定于应用程序的逻辑一无所知,因此客户端代码必须将用户获取器功能注入框架中以使身份验证工作。

关注者
0
被浏览
140
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    参见Raymond Hettinger-超级超级!-PyCon
    2015
    ,有关如何使用超级继承和多重继承而不是DI的争论。如果您没有时间观看整个视频,请跳至第15分钟(但我建议您观看所有视频)。

    这是一个如何将此视频中的内容应用于您的示例的示例:

    框架代码:

    class TokenInterface():
        def getUserFromToken(self, token):
            raise NotImplementedError
    
    class FrameworkClass(TokenInterface):
        def do_the_job(self, ...):
            # some stuff
            self.user = super().getUserFromToken(...)
    

    客户代码:

    class SQLUserFromToken(TokenInterface):
        def getUserFromToken(self, token):      
            # load the user from the database
            return user
    
    class ClientFrameworkClass(FrameworkClass, SQLUserFromToken):
        pass
    
    framework_instance = ClientFrameworkClass()
    framework_instance.do_the_job(...)
    

    这将起作用,因为Python MRO将保证调用getUserFromToken客户端方法(如果使用了super())。如果您使用的是Python2.x,则必须更改代码。

    此处的另一个好处是,如果客户端不提供实现,则会引发异常。

    当然,这并不是真正的依赖注入,它是多个继承和混合,但这是解决问题的Python方法。



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看