5

抽象メソッドを 2 つのメソッドに分けると便利なように思えます。1 つはパブリック インターフェイス用で、もう 1 つはサブクラスによってオーバーライドされます。

このようにして、入力と出力の両方に事前条件/事後条件チェックを追加して、人的エラーに対して堅牢にすることができます。

しかし、私の小さな経験では、このようなコードを見たことがないので、ここでの私の懸念は、それが Python で受け入れられるかどうかです。

通常の多型

import abc

class Shape:
    """Abstract base class for shapes"""
    __metaclass__ = abc.ABCMeta

    @abc.abstractmethod
    def get_area(self, scale):
        """Calculates the area of the shape, scaled by a factor.
        Do not blame for a silly example.
        """
        pass

class Rectangle(Shape):
    def __init__(self, left, top, width, height):
        self.left = left
        self.top = top
        self.width = width
        self.height = height

    def get_area(self, scale):
        return scale * self.width * self.height

print(Rectangle(10, 10, 40, 40).get_area(3))

# Gosh!... gets tons of 3's
print(Rectangle(10, 10, 40, 40).get_area((3,)))

実装方法の分離

import abc

class Shape:
    """Abstract base class for shapes"""
    __metaclass__ = abc.ABCMeta

    def get_area(self, scale):
        """Calculates the area of the shape, scaled by a factor"""

        # preconditions
        assert isinstance(scale, (int,float))
        assert scale > 0

        ret = self._get_area_impl(scale)

        # postconditions
        assert isinstance(ret, (int,float))
        assert ret > 0

        return ret

    @abc.abstractmethod
    def _get_area_impl(self, scale):
        """To be overridden"""
        pass

class Rectangle(Shape):
    def __init__(self, left, top, width, height):
        self.left = left
        self.top = top
        self.width = width
        self.height = height

    def _get_area_impl(self, scale):
        return scale * self.width * self.height

print(Rectangle(10, 10, 40, 40).get_area(3))
print(Rectangle(10, 10, 40, 40).get_area((3,))) # Assertion fails
4

1 に答える 1

0

あなたが説明したものに加えて、私が見る代替案は次のとおりです。

  1. 「実装メソッドの分離」手法を使用しますが、わかりやすい名前を付けます (アンダースコアは使用せず、おそらく のような公開 API と区別できる名前を付けますget_area_from_validated_scale)。私は自分のプロジェクトでこの手法を使用しています。
  2. ユーザーがメソッドをオーバーライドするが、検証を行う基本クラスのメソッドを呼び出す「実装メソッドの分離」手法を実行します。(ただし、入力と出力を検証する必要がある場合は、さらに複雑になります。)
  3. 基本クラスにget_area_validate_inputとの 2 つのメソッドを作成しget_area_validate_output、実装者は を実装するたびにそれらを呼び出す必要がありますget_area
  4. #2 と #3 のバリエーションですが、デコレーターを使用するため、実装@area_validation者はメソッド定義の上に置くだけで済みます。
于 2013-11-16T03:22:09.427 に答える