What is a Pythonic way for Dependency Injection?

后端 未结 9 2054
终归单人心
终归单人心 2020-12-02 06:57

Introduction

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 c

相关标签:
9条回答
  • 2020-12-02 07:50

    Some time ago I wrote dependency injection microframework with a ambition to make it Pythonic - Dependency Injector. That's how your code can look like in case of its usage:

    """Example of dependency injection in Python."""
    
    import logging
    import sqlite3
    
    import boto.s3.connection
    
    import example.main
    import example.services
    
    import dependency_injector.containers as containers
    import dependency_injector.providers as providers
    
    
    class Platform(containers.DeclarativeContainer):
        """IoC container of platform service providers."""
    
        logger = providers.Singleton(logging.Logger, name='example')
    
        database = providers.Singleton(sqlite3.connect, ':memory:')
    
        s3 = providers.Singleton(boto.s3.connection.S3Connection,
                                 aws_access_key_id='KEY',
                                 aws_secret_access_key='SECRET')
    
    
    class Services(containers.DeclarativeContainer):
        """IoC container of business service providers."""
    
        users = providers.Factory(example.services.UsersService,
                                  logger=Platform.logger,
                                  db=Platform.database)
    
        auth = providers.Factory(example.services.AuthService,
                                 logger=Platform.logger,
                                 db=Platform.database,
                                 token_ttl=3600)
    
        photos = providers.Factory(example.services.PhotosService,
                                   logger=Platform.logger,
                                   db=Platform.database,
                                   s3=Platform.s3)
    
    
    class Application(containers.DeclarativeContainer):
        """IoC container of application component providers."""
    
        main = providers.Callable(example.main.main,
                                  users_service=Services.users,
                                  auth_service=Services.auth,
                                  photos_service=Services.photos)
    

    Here is a link to more extensive description of this example - http://python-dependency-injector.ets-labs.org/examples/services_miniapp.html

    Hope it can help a bit. For more information please visit:

    • GitHub https://github.com/ets-labs/python-dependency-injector
    • Docs http://python-dependency-injector.ets-labs.org/
    0 讨论(0)
  • 2020-12-02 07:56

    I think that DI and possibly AOP are not generally considered Pythonic because of typical Python developers preferences, rather that language features.

    As a matter of fact you can implement a basic DI framework in <100 lines, using metaclasses and class decorators.

    For a less invasive solution, these constructs can be used to plug-in custom implementations into a generic framework.

    0 讨论(0)
  • A very easy and Pythonic way to do dependency injection is importlib.

    You could define a small utility function

    def inject_method_from_module(modulename, methodname):
        """
        injects dynamically a method in a module
        """
        mod = importlib.import_module(modulename)
        return getattr(mod, methodname, None)
    

    And then you can use it:

    myfunction = inject_method_from_module("mypackage.mymodule", "myfunction")
    myfunction("a")
    

    In mypackage/mymodule.py you define myfunction

    def myfunction(s):
        print("myfunction in mypackage.mymodule called with parameter:", s)
    

    You could of course also use a class MyClass iso. the function myfunction. If you define the values of methodname in a settings.py file you can load different versions of the methodname depending on the value of the settings file. Django is using such a scheme to define its database connection.

    0 讨论(0)
提交回复
热议问题