智能调度
项目描述
Reg: 智能调度
Reg是一个提供Python通用函数支持的Python库。它可以帮助你为应用程序、库或框架构建强大的注册和配置API。
文档.
构建状态
变更记录
0.12 (2020-01-29)
重大变更
现在,reg.arginfo(callable) 返回的是一个 FullArgSpec 元组,而不是已废弃的 ArgSpec 元组。FullArgSpec 完全支持注解和关键字参数。
修复了 #55。
已移除:移除了对 Python 2 的支持。
如果您想使用此版本,必须升级到 Python 3。
已停止支持 Python 3.3。
增加了对 Python 3.5、3.6、3.7、3.8 和 PyPy 3.6 的支持。
将 Python 3.7 设置为默认测试环境。
添加了 Black 代码格式化器的集成。
0.11 (2016-12-23)
重大变更
已移除 key_predicate 函数。现在您可以使用 Predicate(..., index=KeyIndex) 或 match_key 代替。
重大变更
已移除 class_predicate 函数。现在您可以使用 Predicate(..., index=ClassIndex)、match_instance 或 match_class 代替。
重大变更
已移除未记录的 Sentinel 类和 NOT_FOUND 对象。
重大变更
类 PredicateRegistry 不再是 API 的一部分。内部,类 MultiPredicate、MultiIndex、SingleValueRegistry 都已合并到 PredicateRegistry 中,现在应将其视为实现细节。
match_key 的第二个参数现在是可选的;如果您不提供它,match_key 将生成一个默认提取该名称的谓词函数。
文档现在包括一个描述 Reg 内部的章节。
在发布期间上传通用的 wheels 到 pypi。
0.10 (2016-10-04)
重大变更
Reg 经历了另一项 API 重大变更。这次变更的目标是
使一切明确。
更简单的实现结构 - 调度函数维护自己的注册表,这减少了相互交互的对象。
通过使用具有特殊调度方法的类,使高级上下文相关调度更加 Pythonic。
详细变更
reg.Registry 已消失。现在您可以直接在调度函数上注册
@reg.dispatch('a') def foo(a): ... def foo_implementation(a): ... foo.register(foo_implementation, a=Document)
缓存现在是按调度函数进行的,而不是按全局查找进行。您可以通过将包装 reg.PredicateRegistry 实例的 get_key_lookup 函数放入 reg.DictCachingKeyLookup 缓存来传递。如果您期望调度函数调用具有大量的可能谓词组合,您还可以使用 reg.LruCachingKeyLookup 来保留内存。
“查找” 整个概念已经消失
reg.implicit 已消失:一切都是明确的。没有更多的隐式查找。
reg.Lookup 本身也已消失 - 它现在直接在调度对象中实现,但这是您访问它的方式。
传递当前 Lookup 的特殊 lookup 参数已消失。如果您需要上下文相关调度,请使用调度方法。
如果您需要上下文相关的调度,其中被调用的函数依赖于应用程序上下文(例如 Morepath 的应用程序挂载),请使用 reg.dispatch_method 来创建调度方法。调度方法为每个子类维护一个完全独立的调度注册表。您可以使用 reg.methodify 注册一个接受可选上下文第一个参数的调度函数。
如果您不使用上下文相关的调度功能,那么要升级您的代码
从您的代码中删除任何 reg.set_implicit、Lookup 的设置等。
如果您使用显式 lookup 参数,您只需删除它们。
您还需要更改注册码:不再需要 reg.Registry 设置。
使用 Dispatch.register 将注册改为在调度对象本身上进行。
要启用缓存,您需要在调度函数上设置 get_key_lookup。您可以通过创建 dispatch 的部分应用版本来使此操作更简洁。
import reg from functools import partial def get_caching_key_lookup(r): return reg.CachingKeyLookup(r, 5000, 5000, 5000) dispatch = partial(reg.dispatch, get_key_lookup=get_caching_key_lookup)
dispatch_external_predicates 已被删除。只需直接使用 dispatch。您可以使用 add_predicates 方法将谓词添加到现有的 Dispatch 对象中。
如果您使用上下文相关的调度功能,那么您还需要
在您的应用程序中识别上下文类(或创建一个)。
将调度函数移动到此类中,并用 @reg.dispatch_method 替代 @reg.dispatch。
注册现在使用 <context_class>.<method>.register。以这种方式注册的函数将作为 context_class 的方法执行,因此请将此类的实例作为第一个参数传递。
您还可以使用 reg.methodify 来注册不接受上下文作为第一个参数的实现函数——这在升级现有代码时很有用。
将上下文相关的函数作为上下文实例的方法调用。这样,您可以指明您在何处调用调度方法,而不是使用 lookup 参数。
在某些情况下,您可能需要一个上下文相关的函数,实际上并不在其任何参数上调度。为了支持这种情况,您可以简单地设置一个函数(接受应用程序参数)作为上下文类的方法
Context.my_method = some_function
如果您想要设置一个不将 Context 实例引用作为其第一个参数的函数,您可以使用 reg.methodify 来将其转换为忽略其第一个参数的方法
Context.my_method = reg.methodify(some_function)
如果您想要注册一个可能或可能不包含对 Context 实例引用的 Context 作为其第一个参数的函数,例如称为 app 的函数,您可以使用以下
Context.my_method = reg.methodify(some_function, selfname='app')
重大变更
已从 API 中删除辅助函数 mapply。
重大变更
已从 API 中删除异常类 KeyExtractorError。当向调度函数传递错误数量的参数或使用错误的参数名时,您现在将获得一个 TypeError,符合标准的 Python 行为。
重大变更
已从 API 中删除 KeyExtractor 类。在谓词构造中使用可调用对象现在期望与调度函数相同的参数。
重大变更
已从 Predicate 及其子类中删除 argnames 属性。
重大变更
删除了 match_argname 谓词。现在您可以使用没有可调用对象的 match_instance。
match_class 的第二个参数现在是可选的;如果您不提供它,match_class 将生成一个默认提取该名称的谓词函数。
match_instance 的第二个参数现在是可选的;如果您不提供它,match_instance 将生成一个默认提取该名称的谓词函数。
在 Tox 和 Travis 中包含 doctests。
我们现在使用 virtualenv 和 pip 而不是 buildout 来设置开发环境。相应的开发文档已更新。
由于我们达到了 pytest 的 100% 代码覆盖率,coveralls 集成已被 tox 覆盖率测试中的 --fail-under=100 参数所取代。
0.9.3 (2016-07-18)
对文档进行了小的修复。
为Python 3.4和3.5、PyPy 3和PEP 8添加tox测试环境。
将Python 3.5设为默认Python环境。
修改了导入NoImplicitLookupError的位置,从__init__.py中导入。
0.9.2 (2014-11-13)
Reg的检查过于严格;当存在多个(但不是单个)谓词时,如果在Reg中放入未知键,它会引发KeyError。现在它们只是被静默忽略,因为它们不会造成任何伤害。
消除了在ArgExtractor中不可能发生的检查。
将测试覆盖率恢复到100%。
添加覆盖率配置以在覆盖率报告中忽略测试文件。
0.9.1 (2014-11-11)
在回退逻辑的行为中修复了一个错误。在存在多个谓词(其中一个为类谓词)的情况下,即使有回退可用,也可能找不到回退。
0.9 (2014-11-11)
Reg的全面重写!这包括一系列可能会破坏代码的变化。这次重写的主要动机
将谓词系统与基于类的查找系统统一。
从特定参数中提取调度信息,而不是所有参数。
一些具体变化
将@reg.generic装饰器替换为@reg.dispatch()装饰器。这个装饰器可以用提取参数信息的谓词进行配置。重写这个
@reg.generic def foo(obj): pass
到这个
@reg.dispatch('obj') def foo(obj): pass
还有这个
@reg.generic def bar(a, b): pass
到这个
@reg.dispatch('a', 'b') def bar(a, b): pass
这是为了在这些实例参数的类上进行调度。如果您想匹配参数(例如)的属性类,可以使用带有函数的match_instance。
@reg.dispatch(match_instance('a', lambda a: a.attr))
match_instance的第一个参数是您在register_function中引用谓词的名称。
您也可以使用match_class进行直接的类调度(对于复制类方法很有用),以及使用match_key进行基于参数(不可变)值的调度(对于视图谓词系统很有用)。类似于match_instance,您为这些匹配函数提供函数,从参数中提取调度所需的确切信息。
register_function API替换了register API来注册函数。替换这个
r.register(foo, (SomeClass,), dispatched_to)
为
r.register_function(foo, dispatched_to, obj=SomeClass)
您现在使用关键字参数来明确指出reg.dispatch()指定的那些参数实际上是谓词参数。注册函数时,您无需再担心谓词的顺序。
新的classgeneric功能现在是谓词系统的一部分;您可以使用reg.match_class代替。替换
@reg.classgeneric def foo(cls): pass
为
@reg.dispatch(reg.match_class('cls', lambda cls: cls)) def foo(cls): pass
您现在可以用任何参数这样做,而不仅仅是第一个参数。
pep443支持已移除。Reg专注于自己的调度系统。
组合功能已移除——结果证明Morepath没有使用查找组合来支持应用程序继承。缓存的查找功能已移至registry.py,现在也支持基于谓词的查找缓存。
为了支持一小部分兼容性代码,已移除对future模块的依赖。
0.8 (2014-08-28)
添加了@reg.classgeneric。这与@reg.generic类似,但第一个参数被处理为类,而不是实例。这使得可以用通用函数替换@classmethod。
修复了运行文档测试的文档。由于某种原因,在没有显式运行sphinxpython的情况下,它不再正常工作。
优化:通过使用lookup_mapply而不是通用的mapply来提高通用函数调用的性能,因为我们只关心在定义了查找参数时传入它,其他任何参数都应该像以前一样工作。还添加了一个简单的通用函数计时脚本perf.py。
0.7 (2014-06-17)
Python 2.6兼容性。(Ivo van der Wijk)
类映射(以及因此的通用函数查找)现在也支持旧式类。
在setup.py中将标记为生产/稳定。
0.6 (2014-04-08)
从mapply.py中移除了未使用的代码。
API文档中的错别字已修正。
0.5 (2014-01-21)
将reg.ANY公开。用于匹配任何值的谓词。
0.4 (2014-01-14)
arginfo已完全重写,现在是reg的公共API的一部分。
0.3 (2014-01-06)
得益于future模块,实验性地支持Python 3.3。
0.2 (2013-12-19)
如果通用函数实现定义了一个lookup参数,那么该参数将用于调用它。
添加了reg.mapply()。这允许你调用接受更多关键字参数的函数,忽略那些额外的关键字参数。
返回None的函数不再被认为是失败的,因此不再触发回退到原始通用函数。
在Matcher上提供了一个可选的precalc设施,以避免一些重复计算。
实现一个特定的PredicateMatcher,它根据谓词匹配值。
0.1 (2013-10-28)
首次公开发布。
项目详情
下载文件
下载适用于您平台的文件。如果您不确定要选择哪个,请了解更多关于安装包的信息。