跳转到主要内容

PyContracts 是一个 Python 包,允许在函数参数和返回值上声明约束。约束可以使用 Python3 注解、装饰器或文档字符串中的 :type: 和 :rtype: 标签来指定。PyContracts 支持基本类型系统、变量绑定、算术约束,并提供了一些专用合约(特别是针对 Numpy 数组),以及扩展 API。

项目描述

https://circleci.com/gh/AndreaCensi/contracts.svg?style=svg

PyContracts 是一个 Python 包,允许在函数参数和返回值上声明约束。它支持基本类型系统、变量绑定、算术约束,并提供了一些专用合约(特别是针对 Numpy 数组)。

作为一个快速介绍,请参阅 关于 PyContracts 的这个演示

A presentation about PyContracts

以下是一个简要概述。请参阅完整文档:<http://andreacensi.github.com/contracts/>

原因:PyContracts的目的不是将Python变成静态类型语言(尽管你可以尽可能严格),而是为了避免检查各种前置条件的耗时和混淆。事实上,除了类型约束外,我发现对值和大小约束的强制能力更有用。例如,“我需要一个至少包含3个正数的列表”可以表示为list[>=3](number, >0))。如果你觉得PyContracts对你来说过于复杂,你可能想尝试更简单的替代方案,如typecheck。如果你觉得PyContracts不够用,你可能想使用Haskell而不是Python。

指定契约:契约可以通过三种方式指定

  1. 使用``@contract``装饰器:

    @contract(a='int,>0', b='list[N],N>0', returns='list[N]')
    def my_function(a, b):
        ...
  2. 使用注解(适用于Python 3)

    @contract
    def my_function(a : 'int,>0', b : 'list[N],N>0') -> 'list[N]':
         # Requires b to be a nonempty list, and the return
         # value to have the same length.
         ...
  3. 使用文档字符串,带有:type::rtype:标签

    @contract
    def my_function(a, b):
        """ Function description.
            :type a: int,>0
            :type b: list[N],N>0
            :rtype: list[N]
        """
        ...

部署:在生产环境中,可以使用函数contracts.disable_all()禁用所有检查,因此性能损失为0。

扩展:你可以使用新的契约类型扩展PyContracts

new_contract('valid_name', lambda s: isinstance(s, str) and len(s)>0)
@contract(names='dict(int: (valid_name, int))')
def process_accounting(records):
    ...

任何Python类型都是契约

@contract(a=int, # simple contract
          b='int,>0' # more complicated
          )
def f(a, b):
    ...

强制接口ContractsMeta是一个元类,就像ABCMeta一样,它将契约传播到子类

from contracts import contract, ContractsMeta, with_metaclass

class Base(with_metaclass(ContractsMeta, object)):

    @abstractmethod
    @contract(probability='float,>=0,<=1')
    def sample(self, probability):
        pass

class Derived(Base):
    # The contract above is automatically enforced,
    # without this class having to know about PyContracts at all!
    def sample(self, probability):
        ....

Numpy:有特殊的Numpy支持

@contract(image='array[HxWx3](uint8),H>10,W>10')
def recolor(image):
    ...

状态:语法是稳定的,不会更改。PyContracts在Python 2.x上经过了非常充分的测试。

Python 3.x上的状态:我们已经达到了功能一致性!现在一切都在Python 3上工作。

贡献者:

(如果遗漏了任何人,请告诉我。)

项目详情


下载文件

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

源代码分发

PyContracts-1.8.12.tar.gz (91.4 kB 查看哈希值)

上传时间 源代码

支持