51

私は職場で多数の Python ベースのプロジェクトで DBC の使用を開始しようとしていますが、他の人が DBC でどのような経験をしたのか知りたいと思っています。これまでのところ、私の調査では次のことがわかりました。

  • http://www.python.org/dev/peps/pep-0316/ - 延期された Python の契約による設計を標準化することになっている PEP 316。この PEP は、docstring の使用を提案しています。
  • http://www.wayforward.net/pycontract/ - Python のコントラクト。これは、docstring を使用した完全なフレームワークですが、メンテナンスされていないようです。
  • http://www.nongnu.org/pydbc/ - メタクラスを使用してコントラクトを実装する PyDBC。また、数年間メンテナンスされていません。

私の質問は、Python で DBC を成熟した製品コードに使用したことがありますか? どれくらいうまくいきましたか/努力する価値がありましたか? どのツールをお勧めしますか?

4

5 に答える 5

21

あなたが見つけた PEP はまだ承認されていないため、これを行うための標準的または承認された方法はありません (まだ、いつでも自分で PEP を実装できます!)。ただし、あなたが見つけたように、いくつかの異なるアプローチがあります。

おそらく最も軽量なのは、単純に Python デコレーターを使用することです。Python Decorator Libraryには、非常に簡単に使用できる事前/事後条件用の一連のデコレータがあります。そのページの例を次に示します。

  >>> def in_ge20(inval):
  ...    assert inval >= 20, 'Input value < 20'
  ...
  >>> def out_lt30(retval, inval):
  ...    assert retval < 30, 'Return value >= 30'
  ...
  >>> @precondition(in_ge20)
  ... @postcondition(out_lt30)
  ... def inc(value):
  ...   return value + 1
  ...
  >>> inc(5)
  Traceback (most recent call last):
    ...
  AssertionError: Input value < 20

さて、あなたはクラスの不変条件に言及しています。これらはもう少し難しいですが、不変条件をチェックする callable を定義してから、すべてのメソッド呼び出しの最後に事後条件デコレーターのようなものでその不変条件をチェックするようにする方法があります。最初のカットとして、おそらく postcondition デコレータをそのまま使用できます。

于 2012-01-22T11:08:54.137 に答える
14

私の経験では、言語サポートがなくても、契約による設計には価値があります。メソッドがオーバーライドされていないアサーションの場合、事前条件と事後条件の両方にドキュメント文字列があれば十分です。オーバーライドされるメソッドについては、メソッドを 2 つに分割します。事前条件と事後条件をチェックする public メソッドと、実装を提供し、サブクラスによってオーバーライドされる可能性のある保護されたメソッドです。後者の例を次に示します。

class Math:
    def square_root(self, number)
        """
        Calculate the square-root of C{number}

        @precondition: C{number >= 0}

        @postcondition: C{abs(result * result - number) < 0.01}
        """
        assert number >= 0
        result = self._square_root(number)
        assert abs(result * result - number) < 0.01
        return result

    def _square_root(self, number):
        """
        Abstract method for implementing L{square_root()}
        """
        raise NotImplementedError()

ソフトウェア エンジニアリング ラジオのデザイン バイ コントラクトに関するエピソードから、デザイン バイ コントラクトの一般的な例として平方根を取得しました ( http://www.se-radio.net/2007/03/episode-51-契約による設計/ )。彼らはまた、アサーションはリスコフ置換原理を保証するのに役立たないため、言語サポートの必要性についても言及しましたが、上記の私の例はそうでないことを示すことを目的としています. C++ pimpl (プライベート実装) のイディオムもインスピレーションの源として言及する必要がありますが、それにはまったく別の目的があります。

私の仕事では、最近、この種のコントラクト チェックをより大きなクラス階層にリファクタリングしました (コントラクトは既に文書化されていましたが、体系的にテストされていませんでした)。既存の単体テストでは、コントラクトが複数回違反されていることが明らかになりました。私は、これはずっと前に行われるべきだったと結論付けることしかできません。また、契約による設計が適用されると、単体テストのカバレッジはさらに報われます。この手法の組み合わせを試す人は誰でも同じ観察をすることを期待しています。

ツールのサポートが改善されれば、将来さらに強力になる可能性があります。それは歓迎します。

于 2013-08-09T20:49:16.070 に答える
8

Python で契約による設計を使用したことがないため、すべての質問にお答えすることはできません。ただし、最新バージョンが最近リリースされたコントラクトライブラリを調べるのに時間を費やしましたが、かなり良さそうです。

このライブラリについてredditで議論がありました。

于 2011-12-19T15:41:52.190 に答える
6

契約による正確な設計ではありませんが、一部のテストフレームワークは、概念的に非常に近いプロパティテストアプローチを支持しています。

特定のプロパティが実行時に保持されるかどうかのランダム化されたテストにより、次のことを簡単に確認できます。

  • 不変量
  • 入力値と出力値のドメイン
  • その他の事前条件と事後条件

Pythonには、QuickCheckスタイルのテストフレームワークがいくつかあります。

于 2012-01-24T13:38:41.647 に答える