一个小的依赖注入容器,从php的pimple移植过来

scute的Python项目详细描述


浮渣

Build StatusPyPI Version

scute是python 3.6+的一个小型依赖注入容器,从php的Pimple移植而来,它包括 只有一个文件和一个类(大约100行代码)。

测试套件,甚至这个自述文件,基本上都是Pimple的拷贝粘贴,只对Python进行了轻微的修改 还有一些像injections management through decorators这样的python加法。

所以所有的荣誉都归于Fabien Potencier和粉刺贡献者!

从pypi安装:

    $ pip install scute

然后将其导入到您的代码中,您就可以开始了:

fromscuteimportContainer

创建容器就是设置Container类:

container=Container()

与许多其他依赖注入容器一样,scute能够管理两个 不同类型的数据:servicesparameters

(请注意,快速查看the test suite也可以很好地概述此模块的功能)

定义参数

定义参数就像使用scute实例作为数组一样简单:

# define some parameterscontainer['cookie_name']='SESSION_ID'container['session_storage_class']='SessionStorage'

定义服务

服务是作为更大系统的一部分执行某些操作的对象。 服务示例:数据库连接、模板引擎、mailer。几乎 任何对象都可以是服务。

服务由返回 对象:

#define some servicesdefsession_storage(c:Container):session_storage_class_ref=getattr(importlib.import_module('app'),c['session_storage_class'])returnsession_storage_class_ref(c['cookie_name'])container['session_storage']=session_storagecontainer['session']=labmdac:newSession(c['session_storage'])

注意,该函数可以访问当前容器 实例,允许引用其他服务或参数。

由于只有在获得对象时才创建对象,因此定义的顺序 不要紧,也没有表演惩罚。

使用定义的服务也非常简单:

# get the session objectsession=container['session']# the above call is roughly equivalent to the following code:# storage = app.SessionStorage('SESSION_ID')# session = Session(storage)

定义工厂服务

默认情况下,每次获得服务时,scute都返回它的相同实例。 如果要为所有调用返回不同的实例,请使用factory()方法包装您的可调用实例:

container['session']=container.factory(lambdac:newSession(c['session_storage'])

现在,对container['session']的每个调用都返回会话的一个新实例。

保护参数

因为scute将可调用项视为服务定义,所以您需要 用protect()方法包装匿名函数,将其存储为 参数:

container['random']=container.protect(lambda:randrange(10000))

创建后修改服务

在某些情况下,您可能希望在服务定义 定义。您可以使用extend()方法来定义 在服务创建后立即运行:

container['mail']=lambdac:MailjetApi(user=c['email.user'],password=['email.password'])defextended_email(mail,c:Container):mail.set_from(c['mail.default_from'])returnmailcontainer.extend('mail',extended_email)

第一个参数是对象的名称,第二个参数是 获取对对象实例和容器的访问权限。返回值为 服务定义,因此需要在容器上重新分配它。

获取服务创建函数

当你访问一个对象时,scute会自动调用callable(函数,lambda,callable类…) 您定义的,它为您创建服务对象。如果你想得到 原始访问此函数,可以使用raw()方法:

session_function=container.raw('session')

使用装饰器管理注射

还可以使用decorator管理可调用的依赖项,方法是bind_callable() 并设置依赖项以通过依赖项id的元组注入:

@container.bind_callable(('mailer','signal'))# 'mailer' and 'signal' are injections defined somewhere else on this Containerdefsend_email(mailer:Mailer,email_sent_signal:Signal):mailer.send_email(config)email_sent_signal.send()

但是,如果您添加injection_id参数,这个可调用的也将是服务本身!

@container.bind_callable(('config','mailer','signal'),injection_id='app_mailer')defapp_mailer(config:tuple,mailer:Mailer,signal:Signal):mailer.add_config(config)mailer.set_signal(signal)returnmailer# your container now has a new 'app_mailer' service, that can be injected into other services :-)

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java支持servlet和JSP的使用   java计算模式   Windows上的python PySpark安装异常:Java网关进程在发送其端口号之前退出   java如何解决类中的“Android错误”方法setSupportActionBar?   java JTable为什么单元格颜色不起作用   通过运行时注入实现Java多态性   在Glassfish上使用@EJB注释和Maven的java应用程序客户端   bufferstrategy在java中使用createBufferStrategy()时,拥有2个以上的缓冲区是否有帮助?有什么坏处吗?   用java格式化字符串   带有mvn devserver的Google App Engine Java失败:缺少“guestbook/target/guestbook1.0SNAPSHOT”   java如何测量刚刚收到的UDP数据包大小?   java调用在运行时确定类的泛型方法   java Spring Boot 2.2.4禁用安全性   在java中,如何将文件(通过URL寻址)读入字符串?