What is a Pythonic way for Dependency Injection?

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

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.

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

Leave a Comment