@Idefix_1024: Wobei Du ja nicht einmal das machst was der Code vermuten lässt – das sieht ja so ein bisschen so aus wie man Klassen von `ctypes.Struct` ableiten würde, nur das Du das ja gar nicht machst und damit das `_fields_`-Klassenattribut gar keinen Sinn macht, weil das überhaupt gar keinen Effekt hat. Deinen Code könnte man auch einfach so schreiben:
Code: Alles auswählen
class Signal:
pass
def main():
signal = Signal()
signal.name = 'channel1'
signal.value = [2.5, 2.3, 2.4]
signal.gain = 1.8
signal.offset = 0.2
signal.time = [0, 1, 2]
print(signal.name, signal.value, signal.gain, signal.offset, signal.time)
# -> channel1 [2.5, 2.3, 2.4] 1.8 0.2 [0, 1, 2]
`namedtuple` hat den Vorteil das man bei der Definition des Typs schon sieht welche Attribute es gibt, während bei dem gezeigten Beispiel – und ja auch bei Deinem Code – die Attribute erst nach dem erzeugen des Objekts dynamisch eingeführt werden.
Mit `namedtuple` wird dann auch der Code für die Ausgabe einfacher wenn man einfach nur wissen will was man da vor sich hat, weil man einfach das `signal`-Objekt ausgeben kann und dann nicht nur die Werte sieht, sondern auch die Attributnamen und den Typ des Objekts selbst:
Code: Alles auswählen
from collections import namedtuple
Signal = namedtuple('Signal', 'name value gain offset time')
def main():
signal = Signal('channel1', [2.5, 2.3, 2.4], 1.8, 0.2, [0, 1, 2])
print(signal)
# -> Signal(name='channel1', value=[2.5, 2.3, 2.4], gain=1.8, offset=0.2, time=[0, 1, 2])
Oder das ganze mit dem `attr`-Modul:
Code: Alles auswählen
from attr import attrib, attrs
@attrs(frozen=True)
class Signal:
name = attrib()
value = attrib()
gain = attrib()
offset = attrib()
time = attrib()
def main():
signal = Signal('channel1', [2.5, 2.3, 2.4], 1.8, 0.2, [0, 1, 2])
print(signal)
# -> Signal(name='channel1', value=[2.5, 2.3, 2.4], gain=1.8, offset=0.2, time=[0, 1, 2])
Wobei man sowohl bei `namedtuple` als auch bei `attr` Objekte von diesen Typen verschachteln kann. Auch gegenseitig – also man könnte sowohl bei `Gain` als auch bei `Signal` unabhängig entscheiden ob man das als `namedtuple` oder `attrs`-dekorierte Klasse macht.
Wobei Attributnamen `a`, `b`, und `c` ja irgendwie eher für eine Liste oder ein Tupel sprechen. Das ist ja letztlich nicht viel besser als einen Namen durch zu nummerieren.
Mein persönliches Entscheidungskriterium `namedtuple` vs. `attr`-Modul ist: Wenn es unveränderbar sein soll und keine zusätzlichen Methoden braucht → `namedtuple`, sonst `attr`-Modul.