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

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

问题描述

对于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.

框架代码:

Framework Code:

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

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

客户代码:

Client Code:

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.

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

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:

框架代码:

Framework Code:

class TokenInterface():
    def getUserFromToken(self, token):
        raise NotImplementedError

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

客户代码:

Client Code:

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.

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

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

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

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