名前付きタプルにカスタムイテレータを持つためのpythonic方法はありますか?名前付きタプルのカスタムイテレータ
カスタムイテレータには、インデックス属性が必要なようです。通常、名前付きタプルには "__slots__ =()
"という宣言があり、これは動的辞書のオーバーヘッドを回避し、属性検索の待ち時間を短縮します。ただし、これによりイテレータ(AttributeError: 'Path' object has no attribute '_iidx'
)が破損します。スロットに_iidx
を追加すると、nonempty __slots__ not supported
コンテキスト:私は多数のベジェスプラインで作業します。各スプラインは、「結び目」点のリストと制御点のペアのリストで構成されています。 __slots__ =()
宣言をコメントアウトすると、私のコードが動作します。しかし、インスタンスごとに動的なdictを犠牲にして。属性ルックアップのdictからのオーバヘッドは、おそらく他のすべてに比べて無視できる程度ですが、pythonのようには見えません。
class Path(namedtuple('Path', "knots ctrl_pts")):
# __slots__ =()
@property
def SVG(self):
s = 'M %s' % self.knots[0].bare
for cps, k in self:
s += ' C %s %s' % (cps.bare, k.bare)
return s
def __iter__(self):
self._iidx = 0
return self
def __next__(self):
if self._iidx == len(self.ctrl_pts):
raise StopIteration
i = self._iidx
self._iidx += 1
return (self.ctrl_pts[i], self.knots[i+1])
SVGメソッドでは、イテレータを使用してSVGを簡単に作成します。この:
<path d="M 318.9 179.4 C 279.1 177.6 199.2 270.3 222.4 298.1 C 245.5
326.0 371.6 289.1 420.4 297.0 C 469.2 304.9 440.6 357.6 399.6 352.4
C 388.5 350.9 389.7 345.0 400.4 347.6 C 440.1 357.4 469.4 309.2 419.6
303.0 C 369.8 296.7 240.9 332.5 217.6 301.9 C 194.4 271.2 276.9 174.1
319.1 174.6 C 330.3 174.7 329.9 179.9 318.9 179.4" stroke="black"
stroke-width="1" fill="blue" />
しかし、またGtk.DrawingAreaのon_draw(self, wid, cr):
に使用するのは簡単です::
path = self.coords.outline_path
cr.set_source_rgb(*LT_BLUE)
cr.move_to(*path.knots[0])
for (c,k) in path:
cr.curve_to(*c.P1, *c.P2, *k)
cr.fill_preserve()
cr.set_source_rgb(*BLACK)
cr.stroke()
注: 'ノット' である中
print('<path d="%s" stroke="black" stroke-width="1" fill="blue" />'
% path.SVG)
結果List[Point]
、「ctrl_pts」はList[ControlPoints]
:
class Point(namedtuple('Point', "x y")):
__slots__ =()
"""<bunch of stuff not shown>"""
@property
def bare(self):
return '%.1f %.1f' % (self.x, self.y)
class ControlPoints(namedtuple('ControlPoints', "P1 P2")):
__slots__ =()
@property
def bare(self):
return '%s %s' % (self.P1.bare, self.P2.bare)
です。
私は非常にPythonに新しいですし、これはもっとpythonicの方法で行うことができると確信しています。
「__slots__」は使用しないでください。 – BrenBarn
名前付きタプルに空でない '__slots__'を使用することはできません。 'nonempty __slots__はサポートされていません ' –
私は' __slots__'を使用していないのですか?なぜ__dict__を受け入れないのですか? – BrenBarn