Zuweisung an self.__class__: Ist dieser Code denn noch zu retten?
Verfasst: Sonntag 28. Januar 2018, 19:06
Hallo,
mir ist klar, dass hier zunächst eine Warnung kommen muss: Kinder, macht das nicht zu Hause nach. Zuweisung an self.__class__ ist böse, frisst kleine Kätzchen, oder so.
Nun zu meinem Problem. Wie mache ich es, ohne an __class__ herumzupfuschen? Von so code smell, der mich bitter an Hacks in Perl mit bless erinnert. will ich eigentlich nichts in meinem Programm haben, mir fällt aber leider keine Alternative ein. Kann ein Hinweis auf ein Design bug sein, vielleicht so meine Hoffnung, klärt mich jemand auf.
Den Gedanken, dass in der letzten Zeile "Shape" durch cls ersetzt werden könnte, hab ich schon gehabt. Der liegt ja nahe, scheitert aber leider daran, dass der Konstruktor von SoundGenerator andere Aufrufparameter erwartet als der von seiner Basisklasse.
Das Programm in seiner Gesamtheit funktioniert wie es soll, also grundsätzlich, mein Problem sind halt ein paar hässliche Stellen. Ich hoffe daher, etwaige Änderungsvorschläge sind minimalinvasiv. Falls jemand gerne mehr Kontext hätte – den vollständigen Code zu den zitierten Fragmenten gibt es auf Github: sound_generator.py bzw. shape/__init__.py
Danke!
mir ist klar, dass hier zunächst eine Warnung kommen muss: Kinder, macht das nicht zu Hause nach. Zuweisung an self.__class__ ist böse, frisst kleine Kätzchen, oder so.
Nun zu meinem Problem. Wie mache ich es, ohne an __class__ herumzupfuschen? Von so code smell, der mich bitter an Hacks in Perl mit bless erinnert. will ich eigentlich nichts in meinem Programm haben, mir fällt aber leider keine Alternative ein. Kann ein Hinweis auf ein Design bug sein, vielleicht so meine Hoffnung, klärt mich jemand auf.
Code: Alles auswählen
class SoundGenerator(Shape):
__slots__ = tuple()
def __init__(self, initial, the_list, term):
# ...
super(SoundGenerator, self).__init__((mylist[-2][0], 0), *mylist[1:-1])
del self.coords[0]
@classmethod
def weighted_average(cls, l, dist, r):
if not l.length == r.length:
shorter, longer = sorted((l, r), key=lambda s: s.length )
div = shorter.length / longer.length
shorter.length = longer.length
for c in shorter.coords: c.x *= div
shorter.coords.append( longer.coords[-1].new_alike(y=0) )
self = super().weighted_average(l, dist, r, coord0=False)
self.__class__ = cls
del self.coords[0]
return self
Code: Alles auswählen
class Shape:
__slots__ = ['length', 'coords', 'y_max']
def __init__(self, span, *coords):
@classmethod
def weighted_average (cls, left, dist, right, coord0=True):
"""
Assuming a smooth transition to a right curve in a distance,
Shape.weighted_average(left_shape, distance, right_shape) returns an
intermediate shape at a given position < 1 and > 0.
"""
# ...
return Shape( (adj_length, max_y), *coords[int(coord0):] )
Das Programm in seiner Gesamtheit funktioniert wie es soll, also grundsätzlich, mein Problem sind halt ein paar hässliche Stellen. Ich hoffe daher, etwaige Änderungsvorschläge sind minimalinvasiv. Falls jemand gerne mehr Kontext hätte – den vollständigen Code zu den zitierten Fragmenten gibt es auf Github: sound_generator.py bzw. shape/__init__.py
Danke!