Datentypen: Unterschied zwischen den VersionenAus Attraktor Wiki
Version vom 27. Juli 2022, 16:32 UhrDatentypen sind in Python als Klassen implementiert. >>> type(42) <class 'int'> >>> type(3.14) <class 'float'> >>> type('Hallo') <class 'str'> >>> Deshalb haben sie auch Methoden: >>> dir(int) ['__class__', '__name__', 'from_bytes', 'to_bytes', '__bases__', '__dict__'] >>> dir(str) ['__class__', '__name__', 'count', 'endswith', 'find', 'format', 'index', 'isalpha', 'isdigit', 'islower', 'isspace', 'isupper', 'join', 'lower', 'lstrip', 'replace', 'rfind', 'rindex', 'rsplit', 'rstrip', 'split', 'startswith', 'strip', 'upper', '__bases__', '__dict__', 'center', 'encode', 'partition', 'rpartition', 'splitlines'] >>> dir(float) Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled. Core 1 register dump: PC : 0x400e8bc6 PS : 0x00060630 A0 : 0x800df1a5 A1 : 0x3ffc25d0 A2 : 0x3f409668 A3 : 0x00000002 A4 : 0x3ffc26b0 A5 : 0x00000000 A6 : 0x000000b3 A7 : 0x3ffc2810 A8 : 0x00000000 A9 : 0x3ffc25d0 A10 : 0x00000000 A11 : 0x3ffc2a58 A12 : 0x00000000 A13 : 0x00000000 A14 : 0x00000001 A15 : 0x3f409668 SAR : 0x0000001e EXCCAUSE: 0x0000001c EXCVADDR: 0x00000004 LBEG : 0x4000c46c LEND : 0x4000c477 LCOUNT : 0x00000000 ELF file SHA256: 0000000000000000 Backtrace: 0x400e8bc3:0x3ffc25d0 0x400df1a2:0x3ffc2610 0x400df214:0x3ffc2630 0x400eaa5d:0x3ffc26b0 0x400e34be:0x3ffc26e0 0x400df489:0x3ffc2710 0x400eced9:0x3ffc2730 0x400e3578:0x3ffc27d0 0x400df489:0x3ffc2830 0x400df4b2:0x3ffc2850 0x40117cc8:0x3ffc2870 0x40117dbd:0x3ffc2900 0x400f4a6c:0x3ffc2930 0x40095701:0x3ffc2960 Rebooting... _ __ _ _ _(_)/ _| | _____ __ | | | | | |_| |/ _ \ \ /\ / / | |_| | | _| | (_) \ V V / \__,_|_|_| |_|\___/ \_/\_/ APIKEY: FFBFFD22 ``` NoneAuch None ist eine eigene Klasse: >>> type(None) <class 'NoneType'> >>> >>> dir(None) ['__class__'] >>> Diese Klasse hat aber keine Methoden.
>>> def test_none(): pass >>> a = test_none() >>> a >>> # a liefert keinen Wert zurück # Es geht aber auch einfach, wie fast alles in Python: >>> a = None >>> a >>> >>> a is None True # Der Inhalt von a ist None! >>> >>> a == None # Geht auch, ist aber nicht pythonisch! True >>>
--- Bool ist eine eigene Klasse. Es enthält die Eigenschaften `True` und `False`. Der Versuch Methoden von `bool` zu finden endet im Nirwana bei der Guru Meditation: >>> type(True) <class 'bool'> >>> >>> dir(bool) Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled. Core 1 register dump: PC : 0x400e8bc6 PS : 0x00060730 A0 : 0x800df1a5 A1 : 0x3ffc25d0 A2 : 0x3f40873c A3 : 0x00000002 A4 : 0x3ffc26b0 A5 : 0x00000000 A6 : 0x000000b3 A7 : 0x3ffc2810 A8 : 0x00000000 A9 : 0x3ffc25d0 A10 : 0x00000000 A11 : 0x3ffc2a58 A12 : 0x00000000 A13 : 0x00000000 A14 : 0x00000001 A15 : 0x3f40873c SAR : 0x00000020 EXCCAUSE: 0x0000001c EXCVADDR: 0x00000004 LBEG : 0x4000c46c LEND : 0x4000c477 LCOUNT : 0x00000000 ELF file SHA256: 0000000000000000 Backtrace: 0x400e8bc3:0x3ffc25d0 0x400df1a2:0x3ffc2610 0x400df214:0x3ffc2630 0x400eaa5d:0x3ffc26b0 0x400e34be:0x3ffc26e0 0x400df489:0x3ffc2710 0x400eced9:0x3ffc2730 0x400e3578:0x3ffc27d0 0x400df489:0x3ffc2830 0x400df4b2:0x3ffc2850 0x40117cc8:0x3ffc2870 0x40117dbd:0x3ffc2900 0x400f4a6c:0x3ffc2930 0x40095701:0x3ffc2960 Rebooting... _ __ _ _ _(_)/ _| | _____ __ | | | | | |_| |/ _ \ \ /\ / / | |_| | | _| | (_) \ V V / \__,_|_|_| |_|\___/ \_/\_/ APIKEY: FFBFFD22 `bool` hat wohl keine Methoden.
--- Bytes sind Werte die mit 8-Bit dargestellt werden können (0 ... 255). Bytes kommen als Datentyp in Python nicht vor. Es können aber Zahlen und Strings in eine Bytefolge und umgekehrt umgewandelt werden. Das wird benutzt um Daten zur Übertragung zu serialisieren. Dazu gibt es 2 Datentypen:
--- Wenn man etwas über Python oder auch andere Programmiersprachen ließt, trifft man immer wieder auf den Begriff **Literal**. Was ist damit gemeint? Als Literal bezeichnet man die schriftliche Darstellung einer Zahl. Also z.B. 1, 1.0 oder 1e0. Das sind drei unterschiedliche Literale der Zahl 1.
--- `int` ist die Klasse für ganze Zahlen. Sie enthält alle positiven und negativen ganzen Zahlen. Die Größe eines `int` ist nicht festgelegt. Sie ist praktisch durch die Speichergröße begrenzt. >>> type(42) <class 'int'> >>> type(-42) <class 'int'> >>> type(0) <class 'int'> >>> >>> 10 ** 100 1000000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000 >>> 10 ** 1000000 MemoryError: memory allocation failed, allocating 34258 bytes >>>
```python >>> dir(int) ['__class__', '__name__', 'from_bytes', 'to_bytes', '__bases__', '__dict__'] ```
Wandelt Bytes in ein `int` um. Es muss die Reihenfolge der Bytes angegeben werden, `little` Endian oder `big` Endian. [1](https://www.codegrepper.com/code-examples/python/from_bytes+python) [2](https://www.delftstack.com/de/howto/python/how-to-convert-bytes-to-integers/) [3](https://stackoverflow.com/questions/50509017/how-is-int-from-bytes-calculated)
Wandelt ein `int` in Bytes um. Es muss die Reihenfolge der Bytes angegeben werden, `little` Endian oder `big` Endian.
Bei sehr großen Zahlen unterteilen wir die tausender Stellen gerne mit Punkten. Das ist bei der Eingabe von Zahlen auch in Python möglich. Allerdings wird hier nicht der Punkt, sondern der Unterstrich ‘_’ verwendet: ```python >>> a = 100_000_000 >>> a 100000000 >>> ```
abs(),
--- Die Wesentliche Eigenschaften von `float` wurden schon bei der Vorstellung von Python erörtert. Die Funktionen für `int` lassen auch auf `float` anwenden. Im Modul math gibt es eine Reihe weitere Funktionen, die vor allem für den Typ `float` interssant sind. Eine Übersicht findet man hier: [4](https://docs.micropython.org/en/v1.12/library/math.html) Neben den trigonometrischen und logarithmischen Funktionen gibt es ein paar weitere die ich hier vorstellen möchte: `**math.ceil(*x*)**` Gibt eine ganze Zahl zurück, wobei x auf positive Unendlichkeit gerundet wird. ```python >>> math.ceil(3.14) 4 >>> ``` `**math.copysign(*x*, *y*)**` Gibt x mit dem Vorzeichen von y zurück. ```python >>> math.copysign(math.pi, -1) -3.141593 >>> ``` `**math.fabs(*x*)**` Gibt den absoluten Wert von x zurück. ```python >>> math.copysign(math.pi, -1) -3.141593 >>> math.fabs(_) 3.141593 >>> ``` `**math.floor(*x*)**` Gibt eine ganze Zahl zurück, wobei x gegen negative Unendlichkeit gerundet wird. ```python >>> math.floor(3.14) 3 >>> math.floor(-3.14) -4 >>> ``` `**math.fmod(*x*, *y*)**` Gibt den Rest von x/y zurück. ```python >>> math.fmod(10, 3) 1.0 >>> ``` `**math.isfinite(*x*)**` Gibt `True` zurück, wenn x endlich ist. Endlich ist eine Zahl dann, wenn sie im gültigen Zahlenbereich von `float` liegt. ```python >>> math.isfinite(1e40) False >>> math.isfinite(1e38) True >>> ``` `**math.isinf(*x*)**` Gibt True zurück, wenn x unendlich ist. Unendlich ist eine Zahl dann, wenn sie ausserhalb des gültigen Zahlenbereichs von `float` liegt. ```python >>> math.isinf(1e40) True >>> math.isinf(1e38) False >>> ``` `**math.modf(*x*)**` Gibt ein Tupel aus zwei Floats zurück, die den gebrochenen und den ganzzahligen Teil von x darstellen. Beide Rückgabewerte haben das gleiche Vorzeichen wie x. ```python >>> math.modf(3.14) (0.1400001, 3.0) >>> ``` Hier sieht man einen der gefürchten Rundungsfehler bei floats. `**math.pow(*x*, *y*)**` Gibt x als Potenz von y zurück. ```python >>> math.pow(2, 8) 256.0 >>> ``` `**math.sqrt(*x*)**` Gibt die Quadratwurzel von x zurück. ```python >>> math.sqrt(2) 1.414214 >>> ``` `**math.trunc(*x*)**` ergibt eine ganze Zahl, wobei x gegen 0 gerundet wird. ```python >>> math.trunc(3.14) 3 >>> math.trunc(-3.14) -3 >>> ```
`**math.e**` Die Basis der natürlichen Logarithmen. `**math.pi**` Die Kreiszahl PI, mit begrenzter Genauigkeit. ```python >>> math.pi 3.141593 >>> ```
Da `float` nur eine begrenzte Auflösung bietet, kommt es gelegentlich zu Rundungsfehlern. ```python >>> 10.99999 10.99999 >>> 10.999999 11.0 ``` > Wenn insgesamt mehr als 7 Stellen vorhanden sind wird die Fließkommazahl gerundet! > Der Übergang zum Aufrunden liegt aber bei 0.0000006: ```python >>> 9.99999959 # 9 Stellen 9.999999 >>> 9.9999996 # 8 Stellen 10.0 >>>
>>> 9.99999959999 # 12 Stellen 9.999999 >>> 9.999999599991 # 13 Stellen 10.0 >>> ``` So wie es aussieht wird intern mit 12 Stellen gerechnet und dann auf 7 Stellen gerundet. Ich habe nur sehr selten typische Rundungsfehler in MP gefunden. Die üblichen Beispiele aus dem Internet funktionierten hier nicht. Eine Abhandlung dazu für Python 3.3 ist hier zu finden: [5](https://py-tutorial-de.readthedocs.io/de/python-3.3/floatingpoint.html) .
Aufgrund der Rundungsfehler ist ein direkter Vergleich von floats problematisch. Es wird deshalb empfohlen stattdessen die Abweichung der floats zu ermitteln und zu testen, ob diese geringer als ein zugestandener Fehler ist: `abs(x-y) < eps` . Man kann auch eine entsprechende Funktion schreiben. Hier ein Beispiel in C: ```c bool almostEqual (float a, float b) { return fabs(a - b) <= FLT_EPSILON; } ```
Nan steht für Not a Number, also keine Zahl und existiert nur für floats. Es Bedeutet, das hier kein Wert zur Verfügung steht. ```python >>> n = float('nan') >>> n nan >>> n = float('Nan') >>> n nan >>> n = float('NaN') >>> n nan >>> n = float('NAN') >>> n nan >>> ``` Mit der folgenden Funktion aus dem Modul math kann darauf getestet werden: `**math.isnan(*x*)**` Gibt True zurück, wenn x nicht eine Zahl ist ```python >>> a = 42 >>> n = float('nan') >>> math.isnan(a) False >>> math.isnan(n) True >>> ``` > ‘==’ funktioniert nicht bei nan! > ```python >>> n = float('nan') >>> m = float('nan') >>> n == m False >>> n is m False >>> id(n) 1073493184 >>> id(m) 1073493216 >>> ``` Nan wird verwendet wenn ...
--- |