抽象基本クラスに基づいていくつかのクラスを定義しようとしています。これらの各クラスは、基本的に視覚化パッケージのセル形状を定義します。セルはいくつかの頂点(ポイント)で構成されており、各サブクラスには異なる数のポイントが必要です。各クラスは、固定数の点座標のコンテナと考えることができます。
例として、基本クラスを考えてみましょう。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
ようにしたいと思います。抽象基本クラスとして定義できる方法はありますか?形状の定義を次のように変更してみました。Shape
Shape
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
変更することです。npoints
Shape
@property
def npoints(self):
return _NPOINTS
ただし、次の理由から、抽象基本クラスを使用する利点が失われます。
type
、を使用してクラス属性を定義する方法がわかりません。- 抽象クラス属性を定義する方法がわかりません。
この抽象基本クラスとクラスファクトリ関数、または完全に優れた設計を実装するための最良の方法について誰かが考えていますか?