是否有与Python相对应的Guice(http://code.google.com/p/google-guice)框架?
Spring Python是针对Java的基于Java的Spring框架和Spring Security的分支。该项目当前包含以下功能:
控制反转(依赖注入)-使用经典XML或python @Object装饰器(类似于Spring JavaConfig子项目)将事物连接在一起。虽然@Object格式与Guice样式不同(每个类中的集中布线与布线信息),但这是连接python应用程序的一种有价值的方法。
面向方面的编程-在事务,安全性和缓存之类的水平编程范例(而不是垂直OOP继承)中应用拦截器。
DatabaseTemplate-从数据库读取需要一个单调的周期,即打开游标,读取行和关闭游标以及异常处理程序。使用此模板类,您只需要SQL查询和行处理函数。 Spring Python完成了其余的工作。
数据库事务-用事务包装多个数据库调用会使您的代码难以阅读。该模块提供了多种定义事务的方式,而不会使事情复杂化。
安全-插件安全拦截器可利用身份验证和域授权来锁定对方法的访问。
远程处理-将本地应用程序轻松转换为分布式应用程序很容易。如果您已经使用IoC容器构建了客户端和服务器,则从本地到分布式只是配置更改。
示例-为了帮助演示Spring Python的各种功能,已创建了一些示例应用程序:
PetClinic-Spring Framework的示例Web应用已使用python Web容器从头开始重建,这些容器包括:CherryPy。去看看如何使用这个框架的例子。 (注意:其他python Web框架将来会添加到此列表中)。
Spring Wiki-Wiki是存储和管理内容的强大方法,因此我们创建了一个简单的演示程序!
Spring Bot-使用Spring Python构建一个微型机器人来管理您的开源项目的IRC通道。
值得一提的是SpringPython不支持Python 3,并且自2014年以来没有任何活动...
我喜欢这个简单整洁的框架。
http://pypi.python.org/pypi/injector/
Dependency injection as a formal pattern is less useful in Python than
in other languages, primarily due to its support for keyword
arguments, the ease with which objects can be mocked, and its dynamic
nature.
That said, a framework for assisting in this process can remove a lot
of boiler-plate from larger applications. That's where Injector can
help. It automatically and transitively provides keyword arguments
with their values. As an added benefit, Injector encourages nicely
compartmentalized code through the use of Module s.
While being inspired by Guice, it does not slavishly replicate its
API. Providing a Pythonic API trumps faithfulness.
我没有使用过它,但是Spring Python框架基于Spring并实现了Inversion of Control。
在Python项目中似乎也有一个Guice:snake-guice
作为monkeypatching的替代方法,我喜欢DI。诸如http://code.google.com/p/snake-guice/之类的新生项目可能很合适。
或参见Dennis Kempin的博客文章Dependency Injection in Python(08年8月)。
pinject(https://github.com/google/pinject)是一种较新的替代方法。它似乎由Google维护,并遵循与Java对应的Guice(https://code.google.com/p/google-guice/)类似的模式。
尽管pinject看起来很棒,但它并没有得到多年维护,因为pull请求增加了对Python 2.6和3.x的支持,这种支持已经开放了很长时间。
除此之外:
Zope组件架构
py容器
有一些Guicey的python-inject项目。它非常活跃,比Spring-python少了很多代码,但是话又说回来,我还没有找到使用它的理由。
将把我的5美分留在这里:)
https://pypi.python.org/pypi/dependency_injector
"""Pythonic way for Dependency Injection."""
from dependency_injector import providers
from dependency_injector import injections
@providers.DelegatedCallable
def get_user_info(user_id):
"""Return user info."""
raise NotImplementedError()
@providers.Factory
@injections.inject(get_user_info=get_user_info)
class AuthComponent(object):
"""Some authentication component."""
def __init__(self, get_user_info):
"""Initializer."""
self.get_user_info = get_user_info
def authenticate_user(self, token):
"""Authenticate user by token."""
user_info = self.get_user_info(user_id=token + '1')
return user_info
print AuthComponent
print get_user_info
@providers.override(get_user_info)
@providers.DelegatedCallable
def get_user_info(user_id):
"""Return user info."""
return {'user_id': user_id}
print AuthComponent().authenticate_user(token='abc')
# {'user_id': 'abc1'}
更新
一段时间过去了,Dependency Injector现在有点不同了。最好从Dependency Injector GitHub页面开始以获取实际示例-https://github.com/ets-labs/python-dependency-injector
我喜欢这个答案,因为您提供了代码。如果有机会尝试,我将投票。
嗨@MikeD,谢谢,很高兴听到。这里的代码有些过时了,请转到github.com/ets-labs/python-dependency-injector,这样您就可以找到实际的代码。
如果您只想在Python中进行依赖项注入,则不需要框架。看一下Python方式的依赖注入。这确实非常快捷,简单,只有c。 50行代码。
我不喜欢这篇文章,因为没有真正注入依赖项,并且类将取决于功能定位器。
那是一个框架(有点小)。
这是一个依赖项注入容器的小示例,该容器基于构造函数参数名称进行构造函数注入:
http://code.activestate.com/recipes/576609-non-sive-dependency-injection/
我做了一个lib来做到这一点
https://github.com/ettoreleandrotognoli/python-cdi
希望对您有所帮助
在pypi上可用:https://pypi.python.org/pypi/pycdi
有了它,您可以使用python2进行注入
import logging
from logging import Logger
from pycdi import Inject, Singleton, Producer
from pycdi.shortcuts import call
@Producer(str, _context='app_name')
def get_app_name():
return 'PyCDI'
@Singleton(produce_type=Logger)
@Inject(app_name=str, _context='app_name')
def get_logger(app_name):
return logging.getLogger(app_name)
@Inject(name=(str, 'app_name'), logger=Logger)
def main(name, logger):
logger.info('I\'m starting...')
print('Hello World!!!
I\'m a example of %s' % name)
logger.debug('I\'m finishing...')
call(main)
并使用python3的类型提示
import logging
from logging import Logger
from pycdi import Inject, Singleton, Producer
from pycdi.shortcuts import call
@Producer(_context='app_name')
def get_app_name() -;gt; str:
return 'PyCDI'
@Singleton()
@Inject(logger_name='app_name')
def get_logger(logger_name: str) -;gt; Logger:
return logging.getLogger(logger_name)
@Inject(name='app_name')
def main(name: str, logger: Logger):
logger.info('I\'m starting...')
print('Hello World!!!
I\'m a example of %s' % name)
logger.debug('I\'m finishing...')
call(main)
尽管此链接可以回答问题,但最好在此处包括答案的基本部分,并提供链接以供参考。如果链接的页面发生更改,仅链接的答案可能会失效。 -来自评论
我举了一些例子,现在更好了吗?
现在,其形式的答案肯定会更好。至于内容-我不能说:)
好,谢谢!因此,您只检查答案是否遵循模式而不是内容?
我在此站点的"特殊化"部分看到了您的答案。无论内容如何,??都有关于如何写一个好的答案的指南-您可以在SO上找到它们。当您仅发布链接时-认为它不是一个好答案。您可以发布链接,但应附上您自己的想法,评论,代码等。
我只是试图理解系统,问题很具体;"是否有一个等效于Python的Guice(code.google.com/p/google-guice)的框架?"一个简单的肯定可以回答这个问题。但是我回答:"我做了一些事情来做到这一点。"这还不够好。而这样的答案我喜欢这个简单整洁的框架。 ; lt; lt; link; gt;>;";获得13票。但没关系,我不会为此浪费更多的时间。
除了错误的答案之外,还存在其他问题。同样,你不应该#39;不要用这个词-"不好"。 -从字面上和个人角度。 ;"差"在这种情况下,答案/问题主要是指格式,语法和逻辑结构,而不是内容本身。您引用的问题是一个不好的问题。
只需阅读常见问题解答,即可感觉到一个好的答案/问题的外观。这里有很多错误的答案/问题。他们中有些人已经很老了,他们被视为遗产。它们已关闭,但未删除,因为它们为站点产生了一些流量(有时是很大的流量)。由于该算法尚未发现其他人,因此仍会显示其他人。到目前为止,SO经理不希望将SO变成链接场。您拥有这里提供有意义答案的所有工具。此外,链接本身也不被禁止-仅提供比链接更多的内容。
比框架更简单的是@autowired装饰器。
该装饰器提供了干净的依赖项注入和惰性初始化支持。
变成这样的代码:
def __init__(self, *, model: Model = None, service: Service = None):
if model is None:
model = Model()
if service is None:
service = Service()
self.model = model
self.service = service
# actual code
到这个:
@autowired
def __init__(self, *, model: Model, service: Service):
self.model = model
self.service = service
# actual code
它不是框架,因此尽管它不提供注入上下文操作,但您的设置和执行的工作流程为零。
披露:我是项目维护者。
如果您喜欢一个非常小的解决方案,则可以使用一个小功能,它只是一个依赖设置程序。
https://github.com/liuggio/Ultra-Lightweight-Dependency-Injector-Python
这比直接实例化对象更方便。依赖注入不需要框架。
Enterprython是一个小的框架,提供依赖项注入,可根据类型提示自动构建对象图。
如果您想要这样的向导(如他们所说的新事物),我最近在Python 3中做了一些最适合我对辅助项目的简单需求的事情。
您只需要在方法上使用@inject(当然包括__init__)。
其余的通过注释完成。
from py3njection import inject
from some_package import ClassToInject
class Demo:
@inject
def __init__(self, object_to_use: ClassToInject):
self.dependency = object_to_use
demo = Demo()
https://pypi.python.org/pypi/py3njection
我最近在python中发布了一个用于DI的简洁(IMHO)微库:
https://github.com/suned/serum
dyject(http://dyject.com)是使用内置ConfigParser的适用于Python 2和Python 3的轻量级框架