Konstanten in Struct-Form in Python

9 views
Skip to first unread message

Michael S.

unread,
Feb 19, 2021, 9:27:20 AM2/19/21
to
Hallo Leute,
Ich möchte ein Python Toolset schreiben, mit dem ich sehr einfach auf
Signale in CAN-Botschaften zugreifen kann, die als CAN-Trace vorliegen.
Das parsen des Traces läuft. Nun möchte ich aber die ganzen Infos zu den
CAN-Signalen in einem "Include"-File möglichst einfach zugänglich machen.
Daran scheitere ich.


Tatsächlich gibt es zu jeder CAN-Botschaft mehrere Eigenschaften. Ich
hatte das erstmal so codiert:

class CAN_AC_Voltage:
def __init__(self):
self.ID = 16FC8B11
self.BitOffset = 48
self.BitLength = 8
self.Gain = 1
self.ValueOffset = 0
self.Unit = "V"
self.Rate = 0.5


Dann könnte ich so zugreifen:
CAN_ACV = CAN_AC_Voltage()

ID = CAN_ACV.ID
Unit = CAN_ACV.Unit

Was mich dran nervt ist, dass jede einzelne CAN-Botschaft eine eigene
Klasse ist und ich die im Code erstmal instanzieren muss, bevor ich sie
nutzen kann. Das muss doch auch einfacher gehen.

Ideen?

--
Michael

Hartmut Goebel

unread,
Feb 19, 2021, 9:53:07 AM2/19/21
to
Am 19.02.21 um 15:27 schrieb Michael S.:
> Was mich dran nervt ist, dass jede einzelne CAN-Botschaft eine eigene
> Klasse ist und ich die im Code erstmal instanzieren muss, bevor ich
> sie nutzen kann. Das muss doch auch einfacher gehen
Mache Klassen-Variabblen draus:

class CAN_AC_Voltage:
    ID = 0x16FC8B11
    BitOffset = 48
    BitLength = 8
    Gain = 1
    ValueOffset = 0
    Unit = "V"
    Rate = 0.5

--
Regards
Hartmut Goebel

| Hartmut Goebel | h.go...@crazy-compilers.com |
| www.crazy-compilers.com | compilers which you thought are impossible |

Peter Otten

unread,
Feb 20, 2021, 3:37:16 AM2/20/21
to
from types import SimpleNamespace

CAN_AC_Voltage = SimpleNamespace(
ID=16FC8B11
BitOffset=48
BitLength=8,
...
)

Michael S.

unread,
Feb 22, 2021, 1:00:47 AM2/22/21
to
Am 19.02.2021 um 15:27 schrieb Michael S.:

> Das muss doch auch einfacher gehen.
>
> Ideen?

Ich habs jetzt so gemacht. Da muss ich in der Anwendung nur die
CAN-Signals_Klasse instanzieren, dafür halt in der Lib jeweils jedes
eigene Signal. Aber die Lib wird eh automatisch generiert.

class C_frequency:
def __init__(self):
self.ID = "10FC80FC"
self.BitOffset = 48
self.BitLength = 8
self.Gain = 1
self.ValueOffset = 0
self.Unit = "Hz"
self.Rate = 0.5

class C_OutputVoltage:
def __init__(self):
self.ID = "25FF1250"
self.BitOffset = 32
self.BitLength = 16
self.Gain = 0.1
self.ValueOffset = 0
self.Unit = "V"
self.Rate = 0.25

class C_Cable_temp:
def __init__(self):
self.ID = "12FA5AFC"
self.BitOffset = 0
self.BitLength = 8
self.Gain = 1
self.ValueOffset = -40
self.Unit = "°C"
self.Rate = 10

class CAN_Signals:
def __init__(self):
self.frequency = C_frequency()
self.OutputVoltage = C_OutputVoltage()
self.Cable_temp = C_Cable_temp()



--
Michael

Marc 'BlackJack' Rintsch

unread,
Apr 28, 2021, 6:04:45 AM4/28/21
to
Verschiedene Klassen mit genau den gleichen Attributen sieht ”falsch” aus. Da
würde man eher *eine* Klasse schreiben, die die Attribute hat, und davon dann
mehrere Exemplare erstellen.

Mit `collections.namedtuple()` und Namen die sich an PEP8 halten, könnte das
dann so aussehen:

from collections import namedtuple

Signal = namedtuple(
"Signal", "id bit_offset bit_length gain value_offset unit rate"
)

FREQUENCY = Signal("10FC80FC", 48, 8, 1, 0, "Hz", 0.5)
OUTPUT_VOLTAGE = Signal("25FF1250", 32, 16, 0.1, 0, "V", 0.25)
CABLE_TEMPERATURE = Signal("12FA5AFC", 0, 8, 1, -40, "°C", 10)

Ciao,
Marc 'BlackJack' Rintsch
--
“I don't care WHO you
are but your not walking
on the water while I'm fishing”
Reply all
Reply to author
Forward
0 new messages