環境
- Python 3.6.5
- Windows 10 201903
Design By Contract?
そもそもご存知ない方は ホーア論理 を勉強したほういいと思います。私もこの理論を勉強するまで、事前条件と事後条件の関係を理論的に理解していませんでした。
どんな方法があるのか?
PEP 316で inv を含む Design by Contract の言語拡張提案がなされています。が、Status が Deferred となっていて、言語拡張として DbC がサポートされる見込みはかなり薄そうです。
上記提案を調べていたら、Contracts for Pythonというページを見つけました。PEP 316を意識した実装に見えますが、更新時期が古くちょっと心配です。
PyDBCも更新が2003年と古いです。
PyContractsは最近更新されていて、比較的安心感がありました。Contract の書き方も何パターンかあって面白そうなので見てみました。ただ、invariant や post は書けそうにありません。invariant はパフォーマンス的に不利ですし、invariant をサポートするには atom などさらに拡張が必要なはずなので、致し方ないかと思います。さらに interpreter 側に手を入れる必要があるでしょうから、パッケージで実装することは難しいのではないでしょうか。
始めよう
pip で入れられます。
>pip install PyContracts
サンプルコードを書きました。
# -*- coding: utf-8 -*-
from contracts import contract, ContractsMeta, with_metaclass
@contract
def foo(a, b):
""" Function description.
:type a: int
:type b: int,!=0
"""
return (a/b)
print(foo(1,2))
print(foo(1,0))
後者が契約違反を表示してくれます。いいね。
いいのか?
ホーア理論を教えてくれた先生も言っていたのですが、これなら assert を書くのと何が違うのか?とも思ったりします。ちゃんとできることの差分を調べようと思います。