異議を唱える前に: すべてのプログラマーは怠け者です。そうでなければ、すべてを手動でプログラムして実行することはできません!
簡単な例。
ラインを処理するために必要なすべてを含むクラスLine
があります (2 つの頂点/ポイントを使用して作成されたオブジェクトなど)。このクラスは実際には非常に複雑であり、シンプルさ、保守性、および明確さのために、このように保ちたいと思います: 2 つの頂点を入力し、2 点間の距離などの難しい結果を出力するクラスです。
問題
問題は、これらの個々の行を追跡する必要がある一方で、場合によってはそれらを全体として処理したいことです。たとえば、多くの線で構成されるパスの長さを計算したいと思います。
現在の解決策と欠点
Lines
そのためのいくつかのメソッドも提供するという名前のクラスを作成しました。
Lines
は現在、numpy.ndarray
あまり大きくない子です:
- 名前空間は ndarray のメソッドによって雑然としています。
- のメソッドの周りに
ufunc
ラッパーを提供するために s を使用していますが、このように 2 つの場所でコードを維持するのは面倒です。Lines
Line
質問
Line
では、個々の行を追跡しながらクラスを効率的に「ベクトル化」するにはどうすればよいでしょうか?
すべてを入れて特別なケースLines
と見なすこともできましLine
たが、実際には明確さが損なわれ、個々の行のすべての参照を実装および維持するのが非常に困難になります。
コード例
import numpy as np
class Line:
def __init__ (self, input_points):
assert len(np.array(input_points).squeeze()) == 2
self._points = np.array(input_points)
def get_distance(self):
return np.sqrt(((self._points[0]-self._points[1])**2).sum())
from itertools import combinations
class Lines(np.ndarray):
_get_dists = np.frompyfunc(Line.get_distance, 1, 1)
def __new__(cls, data):
comb = [Line(el) for el in combinations(data, 2)]
obj = np.asarray(comb).view(cls)
obj = obj.squeeze()
return obj
def get_all_distances(self):
return self._get_dists(self)