added unteschiede-note
This commit is contained in:
140
Notes/Unterschiede.md
Normal file
140
Notes/Unterschiede.md
Normal file
@ -0,0 +1,140 @@
|
||||
# Unterschiede zu Vorjahren
|
||||
|
||||
## Typalias
|
||||
|
||||
Manchmal braucht man eine Kombination aus Datentypen
|
||||
|
||||
### Vorher
|
||||
|
||||
Erstellen von Typaliasen mit `Union`
|
||||
|
||||
```python
|
||||
from typing import Union
|
||||
|
||||
# `RealNumber` ist also eine `int` oder eine `float`
|
||||
RealNumber = Union[int, float]
|
||||
|
||||
# also geht hier
|
||||
# `add(1, 1) -> 2`
|
||||
# `add(1.0, 1.0) -> 2.0`
|
||||
# aber auch
|
||||
# `add(1, 1.0) -> 2.0`
|
||||
def add(x: RealNumber, y: RealNumber) -> RealNumber:
|
||||
return x + y
|
||||
```
|
||||
|
||||
### In Python3.12
|
||||
|
||||
Wir haben jetzt das `type`-Keyword für das wir nichts importieren müssen und können einfach Datentypen mit `|` *odern*
|
||||
|
||||
```python
|
||||
# `type` statt `Union`
|
||||
type NewRealNumber = int | float
|
||||
|
||||
# sonst sieht alles gleich aus
|
||||
def new_add(x: NewRealNumber, y: NewRealNumber) -> NewRealNumber:
|
||||
return x + y
|
||||
```
|
||||
|
||||
## Generiche Typ-Parameter (Generics, Typvariabeln, ...)
|
||||
|
||||
### Vorher
|
||||
|
||||
Erstellen von generischen Typvariabeln/Typ-Parametern mit `TypeVar` aus `typing`:
|
||||
|
||||
```python
|
||||
from typing import Generic, TypeVar, Optional
|
||||
from dataclasses import dataclass, field
|
||||
|
||||
# T ist unser Platzhalten für einen beliebigen Datentyp
|
||||
T = TypeVar('T')
|
||||
|
||||
# jetzt können wir `T` einfach als Platzhalter für einen beliebigen Datentyp verwenden
|
||||
# praktisch weil wir so wissen dass `x`, `y` und der `return` zumindest den **selben** Datentyp verwenden
|
||||
# aber welcher genau wissen wir nicht bis jemand die Funktion mit z.b. `int` oder `float`!
|
||||
# Zum Beispiel bedeutet dass
|
||||
# `add(1, 2) == 3` => `T == int`
|
||||
# `add(1.0, 2.0) == 3.0` => `T == float`
|
||||
# ...
|
||||
def add(x: T, y: T) -> T:
|
||||
return x + y
|
||||
|
||||
# Ebenso können wir `T` auch für Klassen verwenden
|
||||
@dataclass
|
||||
# wir müssen hier festlegen dass T in der Klasse verwendet wird
|
||||
# indem `MyList` von `Generic[UnsereGenerischeVariabel]` erbt
|
||||
class MyList(Generic[T]):
|
||||
|
||||
def __post_init__(self, ):
|
||||
# wir haben intern eine `internal_list` die von außen nicht sichtbar ist
|
||||
self.__internal_list: list[T] = field(default_factory=list)
|
||||
# hier speichern wir uns die aktuelle Länge unserer Liste
|
||||
self.__length: int = 0
|
||||
|
||||
def append(self, value: T):
|
||||
"""fügt ein element mit dem Typ `T` hinzu"""
|
||||
self.__internal_list += [value]
|
||||
self.__length += 1
|
||||
|
||||
def remove(self, value: T):
|
||||
"""entfert das element `value`, wenn es in unserer Liste ist"""
|
||||
if value in self.__internal_list:
|
||||
self.__internal_list.remove(value)
|
||||
|
||||
def get(self, i: int) -> Optional[T]:
|
||||
"""gibt das element an `i` Stelle zurück. Wenn Liste kleiner als `i` ist, dann `None`"""
|
||||
if i < len(self):
|
||||
return self[i]
|
||||
return None
|
||||
|
||||
def __len__(self) -> int:
|
||||
return self.__length
|
||||
|
||||
def __getitem__(self, i: int) -> T:
|
||||
return self.__internal_list[i]
|
||||
```
|
||||
|
||||
### In Python3.12
|
||||
|
||||
Deklaration der Typvariabel direkt im Funktionskopf/Klassenkopf mit `[]`.
|
||||
Sprich wir brauchen `TypeVar` nicht mehr
|
||||
|
||||
```python
|
||||
from typing import Optional
|
||||
from dataclasses import dataclass, field
|
||||
|
||||
|
||||
# hier wird `V` durch `[V]` deklariert und kann in der Funktion benutzt werden
|
||||
def new_add[V](x: V, y: V) -> V:
|
||||
return x + y
|
||||
|
||||
|
||||
# hier wird `T` für die Klasse `NewMyList` deklariert durch `[T]` und kann überall in der Klasse genutzt werden
|
||||
# der Rest ist genau gleich, das einzige was sich eben geändert hat ist dass man dieses `TypeVar` nicht mehr braucht
|
||||
# sondern direkt in der Deklaration von Klassen/Funktionen/Methoden die generischen Typvariabeln mit deklariert
|
||||
@dataclass
|
||||
class NewMyList[T]:
|
||||
|
||||
def __post_init__(self, ):
|
||||
self.__internal_list: list[T] = field(default_factory=list)
|
||||
self.__length: int = 0
|
||||
|
||||
def append(self, value: T):
|
||||
self.__internal_list += [value]
|
||||
self.__length += 1
|
||||
|
||||
def remove(self, value: T):
|
||||
if value in self.__internal_list:
|
||||
self.__internal_list.remove(value)
|
||||
|
||||
def get(self, i: int) -> Optional[T]:
|
||||
if i < len(self):
|
||||
return self[i]
|
||||
return None
|
||||
|
||||
def __len__(self) -> int:
|
||||
return self.__length
|
||||
|
||||
def __getitem__(self, i: int) -> T:
|
||||
return self.__internal_list[i]
|
||||
```
|
68
Notes/src/unterschiede.py
Normal file
68
Notes/src/unterschiede.py
Normal file
@ -0,0 +1,68 @@
|
||||
from typing import Generic, TypeVar, Optional, Union
|
||||
from dataclasses import dataclass, field
|
||||
|
||||
T = TypeVar('T')
|
||||
|
||||
@dataclass
|
||||
class MyList(Generic[T]):
|
||||
|
||||
def __post_init__(self, ):
|
||||
self.__internal_list: list[T] = field(default_factory=list)
|
||||
self.__length: int = 0
|
||||
|
||||
def append(self, value: T):
|
||||
self.__internal_list += [value]
|
||||
self.__length += 1
|
||||
|
||||
def remove(self, value: T):
|
||||
if value in self.__internal_list:
|
||||
self.__internal_list.remove(value)
|
||||
|
||||
def get(self, i: int) -> Optional[T]:
|
||||
if i < len(self):
|
||||
return self[i]
|
||||
return None
|
||||
|
||||
def __len__(self) -> int:
|
||||
return self.__length
|
||||
|
||||
def __getitem__(self, i: int) -> T:
|
||||
return self.__internal_list[i]
|
||||
|
||||
@dataclass
|
||||
class MyListNew[T]:
|
||||
|
||||
def __post_init__(self, ):
|
||||
self.__internal_list: list[T] = field(default_factory=list)
|
||||
self.__length: int = 0
|
||||
|
||||
def append(self, value: T):
|
||||
self.__internal_list += [value]
|
||||
self.__length += 1
|
||||
|
||||
def remove(self, value: T):
|
||||
if value in self.__internal_list:
|
||||
self.__internal_list.remove(value)
|
||||
|
||||
def get(self, i: int) -> Optional[T]:
|
||||
if i < len(self):
|
||||
return self[i]
|
||||
return None
|
||||
|
||||
def __len__(self) -> int:
|
||||
return self.__length
|
||||
|
||||
def __getitem__(self, i: int) -> T:
|
||||
return self.__internal_list[i]
|
||||
|
||||
|
||||
RealNumber = Union[int, float]
|
||||
|
||||
def add(x: RealNumber, y: RealNumber) -> RealNumber:
|
||||
return x + y
|
||||
|
||||
type NewRealNumber = int | float
|
||||
|
||||
# sonst sieht alles gleich aus
|
||||
def new_add(x: NewRealNumber, y: NewRealNumber) -> NewRealNumber:
|
||||
return x + y
|
Reference in New Issue
Block a user