Seite 1 von 1
Code aus .h Datei "entschlüsseln"
Verfasst: Samstag 14. August 2021, 14:20
von YAPD
Hi Zusammen,
kann mir jemand vielleicht erklären, was der äquivalente Code in
reinem Python für folgenden Code wäre :
Code: Alles auswählen
typedef enum {
START_RECORD, START_FIELD, ESCAPED_CHAR, IN_FIELD,
IN_QUOTED_FIELD, ESCAPE_IN_QUOTED_FIELD, QUOTE_IN_QUOTED_FIELD,
EAT_CRNL,AFTER_ESCAPED_CRNL
} ParserState;
Ich weiß dass es typedef so in Python nicht gibt, man müsste es praktisch
umschreiben. Ist "ParserState" dann ein Objekt ?
VG
YAPD
Re: Code aus .h Datei "entschlüsseln"
Verfasst: Samstag 14. August 2021, 14:42
von rogerb
@YAPD,
das ist eine Deklaration für ein Enum in C.
"ParseState" ist der Name des Enum.
Enum gibt es in Python auch. Da muss man allerdings direkt Werte angeben:
Code: Alles auswählen
from enum import Enum, auto
class ParserState(Enum):
START_RECORD = auto()
START_FIELD = auto()
ESCAPED_CHAR = auto()
IN_FIELD = auto()
IN_QUOTED_FIELD = auto()
ESCAPE_IN_QUOTED_FIELD = auto()
QUOTE_IN_QUOTED_FIELD = auto()
EAT_CRNL = auto()
AFTER_ESCAPED_CRNL = auto()
Statt auto() kann man auch beliebige Werte angeben. auto() nummeriert einfach die Zahlen von 1.. bis durch.
Re: Code aus .h Datei "entschlüsseln"
Verfasst: Samstag 14. August 2021, 14:48
von YAPD
rogerb hat geschrieben: Samstag 14. August 2021, 14:42
@YAPD,
das ist eine Deklaration für ein Enum in C.
"ParseState" ist der Name des Enum.
Enum gibt es in Python auch. Da muss man allerdings direkt Werte angeben:
Code: Alles auswählen
from enum import Enum, auto
class ParserState(Enum):
START_RECORD = auto()
START_FIELD = auto()
ESCAPED_CHAR = auto()
IN_FIELD = auto()
IN_QUOTED_FIELD = auto()
ESCAPE_IN_QUOTED_FIELD = auto()
QUOTE_IN_QUOTED_FIELD = auto()
EAT_CRNL = auto()
AFTER_ESCAPED_CRNL = auto()
Statt auto() kann man auch beliebige Werte angeben. auto() nummeriert einfach die Zahlen von 1.. bis durch.
Ah OK, danke dir. Das ist interessant. Da es eigentlich nur ein
Objekt ist, das zurückgegeben wird, dachte ich mir, vielleicht
einfach so :
Code: Alles auswählen
class ParserState() :
def __init__(self) :
Self.START_RECORD = None
Self.START_FIELD = None
Self.ESCAPED_CHAR = None
Self.IN_FIELD = None
Self.IN_QUOTED_FIELD = None
Self.ESCAPE_IN_QUOTED_FIELD = None
Self.QUOTE_IN_QUOTED_FIELD = None
Self.EAT_CRNL = None
Self.AFTER_ESCAPED_CRNL = None
x = ParserState( )
Im Prinzip macht es doch nichts anderes oder ?
Bei deienm Beispiel erhalte ich :
Code: Alles auswählen
TypeError: __call__() missing 1 required positional argument: 'value'
VG
YAPD
Re: Code aus .h Datei "entschlüsseln"
Verfasst: Samstag 14. August 2021, 14:54
von nezzcarth
YAPD hat geschrieben: Samstag 14. August 2021, 14:48
Im Prinzip macht es doch nichts anderes oder ?
So als Faustformel sagt man normalerweise, dass man tendenziell keine Klasse schreibt, die keine Methoden umfasst, die auf den gekapselten Daten operieren. In dem Fall würden man dann eher zu einem namedtuple greifen. Enums in Python haben aber davon abweichende Eigenschaften, wie der Name (Enumeration) schon andeutet; sie sind in der Standardvariante im Grunde eine Sammlung (semantisch zusammenhängender) geordneter Konstanten, bzw. Namen für Magic Values.
Re: Code aus .h Datei "entschlüsseln"
Verfasst: Samstag 14. August 2021, 17:42
von rogerb
@YAPD,
du erhältst den Fehler, weil du Enum falsch benutzt.
So würde man eine Instanz einer Klasse erzeugen. Das geht bei einem Enum nicht.
Bei einem Enum ist das Datenfeld, der Wert selbst (hoffe das mach Sinn?)
Ein (etwas konstruiertes) Beispiel:
Code: Alles auswählen
from enum import Enum
class Switch(Enum):
ON = 0
OFF = 1
class Radio():
def __init__(self):
self.state = Switch.OFF
def turn_on(self):
self.state = Switch.ON
def turn_off(self):
self.state = Switch.OFF
def __repr__(self):
return f"<Radio state: {self.state}>"
radio = Radio()
radio.turn_on()
print(radio)
"""
Ausgabe:
<Radio state: Switch.ON>
"""
Wie du siehst haben ON und OFF bestimmte Werte (0 und 1). Diese werden vordergründig aber nicht genutzt.
Man kann ein Enum auch durch eine einfache Klasse ersetzen:
Dann würde aber der Wert der Attribute ausgegeben:
Es gibt Enums in dieser Form noch nicht sehr lange in Python. Man kann auch oft mit anderen Mitteln den gleichen Zweck erreichen. Hier zum Beispiel mit einer einfachen Konstanten:
Außerdem:
Die ParserState Klasse, die du gepostet hattest, ist nicht mit einem Enum zu vergleichen, da man mehrere Instanzen davon bilden könnte. Das macht bei einem Enum keinen Sinn. Man möchte es sogar vermeiden.
Re: Code aus .h Datei "entschlüsseln"
Verfasst: Samstag 14. August 2021, 18:38
von YAPD
nezzcarth hat geschrieben: Samstag 14. August 2021, 14:54
So als Faustformel sagt man normalerweise, dass man tendenziell keine Klasse schreibt, die keine Methoden umfasst, die auf den gekapselten Daten operieren. In dem Fall würden man dann eher zu einem namedtuple greifen. Enums in Python haben aber davon abweichende Eigenschaften, wie der Name (Enumeration) schon andeutet; sie sind in der Standardvariante im Grunde eine Sammlung (semantisch zusammenhängender) geordneter Konstanten, bzw. Namen für Magic Values.
Das habe ich mir schon eigentlich so gemerkt, aber manchmal scheint es doch angebracht zu sein,
wie globale Variablen zu benutzen.
@RogerB :
Vielen Dan auch für dein Beispiel bzgl. ENUM. Der Sinn erschließt sich noch nicht so
ganz dahinter, aber das kriege ich och noch raus
Die ParserState Klasse, die du gepostet hattest, ist nicht mit einem Enum zu vergleichen, da man mehrere Instanzen davon bilden könnte. Das macht bei einem Enum keinen Sinn. Man möchte es sogar vermeiden.
Könntest du das noch ein bisschen ausführen ?
Re: Code aus .h Datei "entschlüsseln"
Verfasst: Samstag 14. August 2021, 19:05
von rogerb
@YAPD,
Bei einem Enum geht es ja darum , dass man EINEN Satz von verschiedenen gleichartigen "Eigenschaften" hat. Zum Beispiel Farben:
Color.RED, Color.BLUE, Color.GREEN
oder Zustände
State.ON, State.OFF
Daher sollte es nur EINEN Satz Farben und EINEN Satz Zustände geben. Mehr braucht man nicht und mehr wäre auch verwirrend.
Instanzen von Klassen sind ja eigenständige Objekte nach dem gleichen Bauplan gebaut. Da will man bewusst verschiedene Versionen also Instanzen, der gleichen Art verwalten. Da braucht man mehrere Objekte.
Bei deiner Klassendeklaration waren die Attribute als Instanzattribute angelegt. (Verwendung von "self")
Wären die Attribute als Klassenattribute angelegt, würden sie der Klasse und nicht der Instanz "gehören". Dann gäbe es jedes Attribut nur einmal und das käme dem Enum daher näher.
Hoffe das macht Sinn.
Re: Code aus .h Datei "entschlüsseln"
Verfasst: Samstag 14. August 2021, 22:52
von __blackjack__
Da die `Enum`-Werte Singletons sind, also jeweils nur *einmal* existieren, kann (und sollte) man die in der Regel dann auch mit ``is`` und ``is not`` vergleichen.
Vor dem `enum`-Modul hätte man den C-Code in Python so umgesetzt:
Code: Alles auswählen
(
START_RECORD,
START_FIELD,
ESCAPED_CHAR,
IN_FIELD,
IN_QUOTED_FIELD,
ESCAPE_IN_QUOTED_FIELD,
QUOTE_IN_QUOTED_FIELD,
EAT_CRNL,
AFTER_ESCAPED_CRNL,
) = range(9)
Mit dem `enum`-Modul müsste man eigentlich `IntEnum` statt `Enum` verwenden. Allerdings hat man dann den gleichen Nachteil, den man auch in C hat: das sind eigentlich nur Namen für ganze Zahlen und man kann verschiedene Enums miteinander vergleichen, die man eigentlich nicht vergleichen können sollte:
Code: Alles auswählen
In [89]: class A(IntEnum):
...: FOO = 0
...: BAR = 1
...:
In [90]: class B(IntEnum):
...: ONE = 1
...: TWO = 2
...:
In [91]: A.BAR == B.ONE
Out[91]: True
Das kann zu Fehlern führen weil man Äpfel mit Birnen vergleicht. Bei `Enum` geht das nicht:
Code: Alles auswählen
In [92]: class A(Enum):
...: FOO = 0
...: BAR = 1
...:
In [93]: class B(Enum):
...: ONE = 1
...: TWO = 2
...:
In [94]: A.BAR == B.ONE
Out[94]: False
Das wäre auch `False` wenn Name *und* Wert in beiden `Enum`-Werten gleich wären, weil es ein unterschiedlicher Datentyp ist.