什么是依赖注入的 Pythonic 方式? [英] What is a Pythonic way for Dependency Injection?

查看:24
本文介绍了什么是依赖注入的 Pythonic 方式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

For Java, Dependency Injection works as pure OOP, i.e. you provide an interface to be implemented and in your framework code accept an instance of a class that implements the defined interface.

现在对于 Python,您可以使用相同的方法,但我认为该方法对于 Python 来说开销太大了.那么你将如何以 Pythonic 的方式实现它?

Now for Python, you are able to do the same way, but I think that method was too much overhead right in case of Python. So then how would you implement it in the Pythonic way?

说这是框架代码:

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

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

基本方法

最天真的(也许是最好的?)方法是要求将外部函数提供给 FrameworkClass 构造函数,然后从 do_the_job 方法调用.

The Basic Approach

The most naive (and maybe the best?) way is to require the external function to be supplied into the FrameworkClass constructor, and then be invoked from the do_the_job method.

框架代码:

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 方法来做到这一点?或者可能有任何支持此类功能的库?

Question

The question is short. Is there any better commonly used Pythonic way to do this? Or maybe any libraries supporting such functionality?

想象一下,我开发了一个微型 Web 框架,它使用令牌处理身份验证.这个框架需要一个函数来提供一些从令牌中获得的 ID 并获取与该 ID 对应的用户.

Imagine I develop a micro web framework, which handles authentication using tokens. This framework needs a function to supply some ID obtained from the token and get the user corresponding to that ID.

显然,框架对用户或任何其他特定于应用程序的逻辑一无所知,因此客户端代码必须将用户 getter 功能注入框架以进行身份​​验证.

Obviously, the framework does not know anything about users or any other application specific logic, so the client code must inject the user getter functionality into the framework to make the authentication work.

推荐答案

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

See Raymond Hettinger - Super considered super! - PyCon 2015 for an argument about how to use super and multiple inheritance instead of DI. If you don't have time to watch the whole video, jump to minute 15 (but I'd recommend watching all of it).

以下是如何将本视频中描述的内容应用于您的示例的示例:

Here is an example of how to apply what's described in this video to your example:

框架代码:

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()).如果您使用的是 Python 2.x,代码将不得不更改.

This will work because the Python MRO will guarantee that the getUserFromToken client method is called (if super() is used). The code will have to change if you're on Python 2.x.

这里的另一个好处是,如果客户端不提供实现,这将引发异常.

One added benefit here is that this will raise an exception if the client does not provide a implementation.

当然,这不是真正的依赖注入,它是多重继承和混合,但它是解决您问题的 Pythonic 方式.

Of course, this is not really dependency injection, it's multiple inheritance and mixins, but it is a Pythonic way to solve your problem.

这篇关于什么是依赖注入的 Pythonic 方式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆