跳转到主要内容

智能调度

项目描述

Reg: 智能调度

Reg是一个提供Python通用函数支持的Python库。它可以帮助你为应用程序、库或框架构建强大的注册和配置API。

文档.

构建状态

https://travis-ci.org/morepath/reg.svg?branch=master https://coveralls.io/repos/github/morepath/reg/badge.svg?branch=master

变更记录

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_instancematch_class 代替。

  • 重大变更

    已移除未记录的 Sentinel 类和 NOT_FOUND 对象。

  • 重大变更

    PredicateRegistry 不再是 API 的一部分。内部,类 MultiPredicateMultiIndexSingleValueRegistry 都已合并到 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_implicitLookup 的设置等。

    • 如果您使用显式 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)

  • 首次公开发布。

项目详情


下载文件

下载适用于您平台的文件。如果您不确定要选择哪个,请了解更多关于安装包的信息。

源分布

reg-0.12.tar.gz (55.1 kB 查看散列)

上传时间

构建分布

reg-0.12-py2.py3-none-any.whl (29.8 kB 查看散列)

上传时间 Python 2 Python 3

由以下赞助

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误记录 StatusPage StatusPage 状态页面