1

抽象基本クラスに基づいていくつかのクラスを定義しようとしています。これらの各クラスは、基本的に視覚化パッケージのセル形状を定義します。セルはいくつかの頂点(ポイント)で構成されており、各サブクラスには異なる数のポイントが必要です。各クラスは、固定数の点座標のコンテナと考えることができます。

例として、基本クラスを考えてみましょう。Shapeこれは、座標のリストの単なるコンテナです。

class Shape(object):
    """Cell shape base class."""
    def __init__(self, sequence):
        self.points = sequence

    @property
    def points(self):
        return self._points

    @points.setter
    def points(self, sequence):
        # Error checking goes here, e.g. check that `sequence` is a
        # sequence of numeric values.
        self._points = sequence

理想的には、たとえば、メソッドが長さ4のSquareクラスをpoints.setterチェックできるようにする必要があります。さらに、ユーザーがインスタンス化できないsequenceようにしたいと思います。抽象基本クラスとして定義できる方法はありますか?形状の定義を次のように変更してみました。ShapeShape

import abc

class Shape(object):
    """Cell shape base class."""

    __metaclass__ = abc.ABCMeta

    def __init__(self, sequence):
        self.points = sequence

    @abc.abstractproperty
    def npoints(self):
        pass

    @property
    def points(self):
        return self._points

    @points.setter
    def points(self, sequence):
        # Error checking goes here...
        if len(sequence) != self.npoints:
            raise TypeError('Some descriptive error message!')

        self._points = sequence

これには、プロパティを定義するためのサブクラスが必要npointsです。Square次に、クラスを次のように定義できます。

class Square(Shape):
    @property
    def npoints(self):
        return 4

ただし、これを実装するのはかなり面倒です(実装するプロパティが複数ある場合)。私は自分のサブクラスを作成するクラスファクトリを定義したいと思っていました。

def Factory(name, npoints):
    return type(name, (Shape,), dict(npoints=npoints))

Triangle = Factory('Triangle', 3)    
Square = Factory('Square', 4)
# etc...

このクラスファクトリ関数は有効なアプローチですか、それともnpointsプロパティを壊してしまいますか?typeの呼び出しを次のようなより冗長なものに置き換える方がよいでしょうか。

def Factory(name, _npoints):
    class cls(Shape):
        @property
        def npoints(self):
            return _npoints
    cls.__name__ = name
    return cls

別のアプローチは、クラス属性を定義し、の プロパティをに_NPOINTS変更することです。npointsShape

@property
def npoints(self):
    return _NPOINTS

ただし、次の理由から、抽象基本クラスを使用する利点が失われます。

  • type、を使用してクラス属性を定義する方法がわかりません。
  • 抽象クラス属性を定義する方法がわかりません。

この抽象基本クラスとクラスファクトリ関数、または完全に優れた設計を実装するための最良の方法について誰かが考えていますか?

4

1 に答える 1

3

あなたのプロジェクトについて詳しく知らなければ、一般的なデザインについて具体的なアドバイスをすることはできません. もう少し一般的なヒントと考えを提供します。

  1. 動的に生成されたクラスは、多くの場合、個別のクラスがまったく必要ないことを示しています。すべての機能を組み込む単一のクラスを作成するだけです。Shapeインスタンス化時にプロパティを取得するクラスの問題は何ですか? (もちろん、動的に生成されたクラスを使用する理由がありnamedtuple()ます。ファクトリ関数はその一例です。しかし、あなたの質問には具体的な理由は見つかりませんでした。)

  2. 多くの場合、抽象基本クラスを使用する代わりに、目的のインターフェイスを単純に文書化し、このインターフェイスに準拠するクラスを記述します。Python の動的な性質により、共通の基本クラスは厳密には必要ありません。共有機能など、共通の基底クラスには他にも利点があることがよくあります。

  3. そうしないと無関係な場所で奇妙なエラーが発生する場合にのみ、アプリケーション コードのエラーをチェックしてください。たとえば、関数がイテラブルを期待している場合は、単にイテラブルを取得したと仮定します。ユーザーが何か他のものを渡した場合、コードが渡されたオブジェクトを反復しようとすると失敗し、通常はアプリケーション開発者がエラーを理解するにはエラー メッセージで十分です。

于 2012-06-12T13:51:36.973 に答える