Direkt zum Inhalt

Python Data Classes: Ein umfassendes Tutorial

Ein einsteigerfreundliches Tutorial über Python-Datenklassen und wie man sie in der Praxis einsetzt
Aktualisierte 16. Jan. 2025  · 9 Min. Lesezeit

Datenklassen sind eine der Funktionen von Python, die du, wenn du sie einmal entdeckt hast, nie wieder verwenden wirst. Betrachte diese reguläre Klasse:

class Exercise:
   def __init__(self, name, reps, sets, weight):
       self.name = name
       self.reps = reps
       self.sets = sets
       self.weight = weight

Meiner Meinung nach ist diese Klassendefinition sehr ineffizient - in der Methode __init__ wiederholst du jeden Parameter mindestens dreimal. Das klingt vielleicht nicht nach einer großen Sache, aber überlege mal, wie oft du in deinem Leben Klassen mit viel mehr Parametern schreibst.

Zum Vergleich: Schau dir die Datenklassen-Alternative des obigen Codes an:

from dataclasses import dataclass


@dataclass
class Exercise:
   name: str
   reps: int
   sets: int
   weight: float  # Weight in lbs

Dieses bescheiden aussehende Stück Code ist um Größenordnungen besser als eine normale Klasse. Der winzige Dekorator @dataclass implementiert die Klassen __init__, __repr__, __eq__ hinter den Kulissen, was manuell mindestens 20 Zeilen Code erfordert hätte.

Außerdem sind viele andere Funktionen wie Vergleichsoperatoren, Objektordnung und Unveränderlichkeit nur eine einzige Zeile davon entfernt, für unsere Klasse erstellt zu werden.

In diesem Tutorial wollen wir dir zeigen, warum Datenklassen das Beste sind, was Python passieren konnte, wenn du objektorientierte Programmierung liebst.

Lass uns loslegen!

Grundlagen der Python-Datenklassen

Im Folgenden werden einige der grundlegenden Konzepte von Python-Datenklassen erläutert, die Python so nützlich machen.

Einige Methoden werden automatisch in Datenklassen generiert

Trotz all ihrer Funktionen sind Datenklassen ganz normale Klassen, die viel weniger Code benötigen, um die gleiche Funktionalität zu implementieren. Hier ist wieder die Exercise Klasse:

from dataclasses import dataclass


@dataclass
class Exercise:
   name: str
   reps: int
   sets: int
   weight: float


ex1 = Exercise("Bench press", 10, 3, 52.5)

# Verifying Exercise is a regular class
ex1.name
'Bench press'

Im Moment hat Exercise bereits die Methoden __repr__ und __eq__ implementiert. Lass es uns überprüfen:

repr(ex1)
"Exercise(name='Bench press', reps=10, sets=3, weight=52.5)"

Die Objektrepräsentation eines Objekts repr muss den Code zurückgeben, der sich selbst wiederherstellen kann, und wir können sehen, dass genau das bei ex1 der Fall ist.

Im Vergleich dazu würde Exercise auf die alte Art und Weise wie folgt aussehen:

class Exercise:
   def __init__(self, name, reps, sets, weight):
       self.name = name
       self.reps = reps
       self.sets = sets
       self.weight = weight


ex3 = Exercise("Bench press", 10, 3, 52.5)

ex3
<__main__.Exercise at 0x7f6834100130>

Sieht ziemlich furchtbar und nutzlos aus!

Überprüfen wir nun die Existenz von __eq__, dem Gleichheitsoperator:

# Redefine the class
@dataclass
class Exercise:
   name: str
   reps: int
   sets: int
   weight: float


ex1 = Exercise("Bench press", 10, 3, 52.5)
ex2 = Exercise("Bench press", 10, 3, 52.5)

Der Vergleich der Klasse mit sich selbst und mit einer anderen Klasse mit identischen Parametern muss True ergeben:

ex1 == ex2
True
ex1 == ex1
True

Und das tut sie auch! Im normalen Unterricht wäre diese Logik mühsam zu schreiben gewesen.

Datenklassen erfordern Typ-Hinweise

Wie du vielleicht schon bemerkt hast, benötigen Datenklassen bei der Definition von Feldern Typ-Hinweise. In der Tat erlauben Datenklassen jeden Typ aus dem typing Modul. So kannst du zum Beispiel ein Feld erstellen, das den Datentyp Any akzeptiert:

from typing import Any


@dataclass
class Dummy:
   attr: Any

Die Besonderheit von Python ist jedoch, dass die Typen nicht erzwungen werden, obwohl die Datenklassen Hinweise auf den Typ benötigen.

Zum Beispiel kann die Erstellung einer Instanz der Klasse Exercise mit völlig falschen Datentypen ohne Fehler ausgeführt werden:

silly_exercise = Exercise("Bench press", "ten", "three sets", 52.5)

silly_exercise.sets

“Three sets”

Wenn du Datentypen erzwingen willst, musst du Typprüfungen wie Mypy verwenden.

Datenklassen erlauben Standardwerte in Feldern

Bis jetzt haben wir unseren Klassen noch keine Vorgaben hinzugefügt. Das müssen wir ändern:

@dataclass
class Exercise:
   name: str = "Push-ups"
   reps: int = 10
   sets: int = 3
   weight: float = 0


# Now, all fields have defaults
ex5 = Exercise()
ex5
Exercise(name='Push-ups', reps=10, sets=3, weight=0)

Denke daran, dass Nicht-Standardfelder nicht auf Standardfelder folgen können. Der folgende Code zum Beispiel wird einen Fehler auslösen:

@dataclass
class Exercise:
   name: str = "Push-ups"
   reps: int = 10
   sets: int = 3
   weight: float  # NOT ALLOWED


ex5 = Exercise()
ex5
TypeError: non-default argument 'weight' follows default argument

In der Praxis wirst du nur selten Standardwerte mit der name: type = value Syntax definieren.

Stattdessen verwendest du die Funktion field, die mehr Kontrolle über die einzelnen Felddefinitionen ermöglicht:

from dataclasses import field


@dataclass
class Exercise:
   name: str = field(default="Push-up")
   reps: int = field(default=10)
   sets: int = field(default=3)
   weight: float = field(default=0)


# Now, all fields have defaults
ex5 = Exercise()
ex5
Exercise(name='Push-up', reps=10, sets=3, weight=0)

Die Funktion field hat mehr Parameter, wie zum Beispiel:

  • repr
  • init
  • compare
  • default_factory

und so weiter. Wir werden diese in den nächsten Abschnitten besprechen.

Datenklassen können mit einer Funktion erstellt werden

Ein letzter Hinweis zu den Grundlagen der Datenklassen ist, dass ihre Definition noch kürzer sein kann, wenn du die Funktion make_dataclass verwendest:

from dataclasses import make_dataclass

Exercise = make_dataclass(
   "Exercise",
   [
       ("name", str),
       ("reps", int),
       ("sets", int),
       ("weight", float),
   ],
)

ex3 = Exercise("Deadlifts", 8, 3, 69.0)
ex3
Exercise(name='Deadlifts', reps=8, sets=3, weight=69.0)

Aber du verlierst dabei die Lesbarkeit, deshalb empfehle ich diese Funktion nicht.

Fortgeschrittene Python-Datenklassen

In diesem Abschnitt werden wir erweiterte Funktionen von Datenklassen besprechen, die mehr Vorteile bringen. Eine solche Funktion ist die Standardfabrik.

Standard-Fabriken

Um die Standardfabriken zu erklären, erstellen wir eine weitere Klasse namens WorkoutSession, die zwei Felder akzeptiert:

from dataclasses import dataclass
from typing import List


@dataclass
class Exercise:
   name: str = "Push-ups"
   reps: int = 10
   sets: int = 3
   weight: float = 0


@dataclass
class WorkoutSession:
   exercises: List[Exercise]
   duration_minutes: int

Indem wir den Typ List verwenden, geben wir an, dass WorkoutSession eine Liste von Exercise Instanzen annimmt.

# Define the Exercise instances for HIIT training
ex1 = Exercise(name="Burpees", reps=15, sets=3)
ex2 = Exercise(name="Mountain Climbers", reps=20, sets=3)
ex3 = Exercise(name="Jump Squats", reps=12, sets=3)
exercises_monday = [ex1, ex2, ex3]

hiit_monday = WorkoutSession(exercises=exercises_monday, duration_minutes=30)

Momentan müssen für jede Trainingseinheit Übungen initialisiert werden. Aber das spiegelt nicht wider, wie die Menschen trainieren - zuerst beginnen sie eine Sitzung (wahrscheinlich in einer App) und fügen dann während des Trainings Übungen hinzu.

Wir müssen also in der Lage sein, Sitzungen ohne Übungen und ohne Dauer zu erstellen. Um dies zu erreichen, fügen wir eine leere Liste als Standardwert für exercises hinzu:

@dataclass
class WorkoutSession:
   exercises: List[Exercise] = []
   duration_minutes: int = None


hiit_monday = WorkoutSession("25-02-2024")
ValueError: mutable default <class 'list'> for field exercises is not allowed: use default_factory

Wir erhielten jedoch einen Fehler - es stellte sich heraus, dass Datenklassen keine veränderbaren Standardwerte zulassen.

Zum Glück können wir das beheben, indem wir eine Standardfabrik verwenden:

@dataclass
class WorkoutSession:
   exercises: List[Exercise] = field(default_factory=list)  # PAY ATTENTION
   duration_minutes: int = 0


hiit_monday = WorkoutSession()
hiit_monday
WorkoutSession(exercises=[], duration_minutes=0)

Der Parameter default_factory akzeptiert eine Funktion, die einen Anfangswert für ein Datenklassenfeld zurückgibt. Das bedeutet, dass sie jede beliebige Funktion annehmen kann:

  • tuple
  • dict
  • set
  • Jede benutzerdefinierte benutzerdefinierte Funktion

Dies gilt unabhängig davon, ob das Ergebnis der Funktion veränderbar ist oder nicht.

Wenn wir darüber nachdenken, beginnen die meisten Menschen ihr Training mit Aufwärmübungen, die für jede Art von Training typisch sind. Es kann also sein, dass der Beginn einer Sitzung ohne Übungen nicht das ist, was manche Leute wollen.

Stattdessen wollen wir eine Funktion erstellen, die drei Aufwärmprogramme zurückgibt Exercises:

def create_warmup():
   return [
       Exercise("Jumping jacks", 30, 1),
       Exercise("Squat lunges", 10, 2),
       Exercise("High jumps", 20, 1),
   ]

@dataclass
class WorkoutSession:
   exercises: List[Exercise] = field(default_factory=create_warmup)
   duration_minutes: int = 5  # Increase the default duration as well


hiit_monday = WorkoutSession()
hiit_monday

WorkoutSession(exercises=[Exercise(name='Jumping jacks', reps=30, sets=1, weight=0), Exercise(name='Squat lunges', reps=10, sets=2, weight=0), Exercise(name='High jumps', reps=20, sets=1, weight=0)], duration_minutes=5)

Wenn wir jetzt eine Unterrichtseinheit erstellen, werden bereits einige Aufwärmübungen aufgezeichnet. Die neue Version von WorkoutSession hat eine Standarddauer von fünf Minuten, um dies zu berücksichtigen.

Hinzufügen von Methoden zu Datenklassen

Da Datenklassen reguläre Klassen sind, bleibt das Hinzufügen von Methoden zu ihnen dasselbe. Fügen wir zwei Methoden zu unserer WorkoutSession Datenklasse hinzu:

@dataclass
class WorkoutSession:
   exercises: List[Exercise] = field(default_factory=create_warmup)
   duration_minutes: int = 5

   def add_exercise(self, exercise: Exercise):
       self.exercises.append(exercise)

   def increase_duration(self, minutes: int):
       self.duration_minutes += minutes

Mit diesen Methoden können wir jetzt jede neue Aktivität in einer Sitzung protokollieren:

hiit_monday = WorkoutSession()

# Log a new exercise
new_exercise = Exercise("Deadlifts", 6, 4, 60)

hiit_monday.add_exercise(new_exercise)
hiit_monday.increase_duration(15)

Aber es gibt ein Problem:

hiit_monday

WorkoutSession(exercises=[Exercise(name='Jumping jacks', reps=30, sets=1, weight=0), Exercise(name='Squat lunges', reps=10, sets=2, weight=0), Exercise(name='High jumps', reps=20, sets=1, weight=0), Exercise(name='Deadlifts', reps=6, sets=4, weight=60)], duration_minutes=20)

Wenn wir die Sitzung ausdrucken, ist ihre Standarddarstellung zu ausführlich und unleserlich, da sie den Code zur Neuerstellung des Objekts enthält. Das müssen wir ändern.

__repr__ und __str__ in Datenklassen

Datenklassen implementieren __repr__ automatisch, aber nicht __str__. So kann die Klasse auf __repr__ zurückgreifen, wenn wir sie zum Drucken aufrufen.

Also setzen wir dieses Verhalten außer Kraft, indem wir __str__ selbst definieren:

@dataclass
class Exercise:
   name: str = "Push-ups"
   reps: int = 10
   sets: int = 3
   weight: float = 0

   def __str__(self):
       base = f"{self.name}: {self.reps}/{self.sets}"
       if self.weight == 0:
           return base
       return base + f", {self.weight} lbs"


ex1 = Exercise(name="Burpees", reps=15, sets=3)
ex1
Exercise(name='Burpees', reps=15, sets=3, weight=0)

Die __repr__ ist immer noch die gleiche, aber wenn wir print aufrufen:

print(ex1)
Burpees: 15/3

Die Frühlingsdarstellung der Klasse ist viel schöner. Und jetzt lass uns auch WorkoutSession reparieren:

@dataclass
class WorkoutSession:
   exercises: List[Exercise] = field(default_factory=create_warmup)
   duration_minutes: int = 5  # Increase the default duration as well

   def add_exercise(self, exercise: Exercise):
       self.exercises.append(exercise)

   def increase_duration(self, minutes: int):
       self.duration_minutes += minutes

   def __str__(self):
       base = ""

       for ex in self.exercises:
           base += str(ex) + "\n"
       base += f"\nSession duration: {self.duration_minutes} minutes."

       return base


hiit_monday = WorkoutSession()
print(hiit_monday)

Jumping jacks: 30/1
Squat lunges: 10/2
High jumps: 20/1

Session duration: 5 minutes.

Hinweis: Verwende die Schaltfläche "Code erklären" am Ende des Snippets, um eine zeilenweise Erklärung des Codes zu erhalten.

Jetzt haben wir eine lesbare und kompakte Ausgabe.

Vergleich in Datenklassen

Bei vielen Klassen ist es sinnvoll, ihre Objekte nach einer bestimmten Logik zu vergleichen. Beim Training kann es die Trainingsdauer, die Trainingsintensität oder das Gewicht sein.

Schauen wir uns zunächst an, was passiert, wenn wir versuchen, zwei Workouts im aktuellen Zustand zu vergleichen:

hiit_wednesday = WorkoutSession()

hiit_wednesday.add_exercise(Exercise("Pull-ups", 7, 3))
print(hiit_wednesday)

Jumping jacks: 30/1
Squat lunges: 10/2
High jumps: 20/1
Pull-ups: 7/3

Session duration: 5 minutes.

hiit_monday > hiit_wednesday
TypeError: '>' not supported between instances of 'WorkoutSession' and 'WorkoutSession'

Wir erhalten eine TypeError, da Datenklassen keine Vergleichsoperatoren implementieren. Das lässt sich aber leicht beheben, indem du den Parameter order auf True setzt:

@dataclass(order=True)
class WorkoutSession:
   exercises: List[Exercise] = field(default_factory=create_warmup)
   duration_minutes: int = 5

   ...

hiit_monday = WorkoutSession()
# hiit_monday.add_exercise(...)
hiit_monday.increase_duration(10)

hiit_wednesday = WorkoutSession()

hiit_monday > hiit_wednesday

True

Dieses Mal funktioniert der Vergleich, aber was vergleichen wir überhaupt?

In Datenklassen wird der Vergleich in der Reihenfolge durchgeführt, in der die Felder definiert sind. Im Moment werden die Klassen anhand der Trainingsdauer verglichen, da das erste Feld, exercises, nicht standardisierte Objekte enthält.

Wir können das überprüfen, indem wir die Dauer der Mittwochssitzung verlängern:

hiit_monday = WorkoutSession()
# hiit_monday.add_exercise(...)

hiit_wednesday = WorkoutSession()
hiit_wednesday.increase_duration(10)

hiit_monday > hiit_wednesday
False

Wie erwartet, haben wir False erhalten.

Was würde aber passieren, wenn das erste Feld von Workout eine andere Art von Feld wäre, zum Beispiel ein String? Lass es uns herausfinden:

@dataclass(order=True)
class WorkoutSession:
   date: str = None  # DD-MM-YYYY
   exercises: List[Exercise] = field(default_factory=create_warmup)
   duration_minutes: int = 5

   ...

hiit_monday = WorkoutSession("25-02-2024")
hiit_monday.increase_duration(10)

hiit_wednesday = WorkoutSession("27-02-2024")

hiit_monday > hiit_wednesday
False

Auch wenn die Montagssitzung länger dauert, zeigt der Vergleich, dass sie kleiner ist als die Mittwochssitzung. Der Grund dafür ist, dass "25" beim Python-Stringvergleich vor "27" kommt.

Wie können wir also die Reihenfolge der Felder beibehalten und die Sitzungen trotzdem nach der Trainingsdauer sortieren? Das geht ganz einfach über die Funktion field:

@dataclass(order=True)
class WorkoutSession:
   date: str = field(default=None, compare=False)
   exercises: List[Exercise] = field(default_factory=create_warmup)
   duration_minutes: int = 5

   ...

hiit_monday = WorkoutSession("25-02-2024")
hiit_monday.increase_duration(10)

hiit_wednesday = WorkoutSession("27-02-2024")

hiit_monday > hiit_wednesday
True

Indem wir compare für ein beliebiges Feld auf False setzen, schließen wir es von der Sortierung aus, wie das obige Ergebnis zeigt.

Manipulation des Post-Init-Feldes

Im Moment haben wir eine Standarddauer von fünf Minuten, um Aufwärmübungen zu berücksichtigen. Das macht aber nur Sinn, wenn ein Nutzer eine Sitzung mit einem Warm-up beginnt. Was ist, wenn sie eine Sitzung mit anderen Übungen beginnen?

new_session = WorkoutSession([Exercise("Diamond push-ups", 10, 3)])

new_session.duration_minutes
5

Für nur eine einzige Übung beträgt die Gesamtdauer fünf Minuten, was unlogisch ist. Jede Einheit muss ihre Dauer dynamisch anhand der Anzahl der Sätze jeder Übung schätzen. Das bedeutet, dass wir duration_minutes von dem Feld exercises abhängig machen sollten.

Lass es uns umsetzen:

@dataclass
class WorkoutSession:
   exercises: List[Exercise] = field(default_factory=create_warmup)
   duration_minutes: int = field(default=0, init=False)

   def __post_init__(self):
       set_duration = 3
       for ex in self.exercises:
           self.duration_minutes += ex.sets * set_duration

   ...

Dieses Mal definieren wir duration_minutes, wobei init auf False gesetzt ist, um die Initialisierung des Feldes zu verzögern.

Dann aktualisieren wir in einer speziellen Methode __post_init__ den Wert auf der Grundlage der Gesamtzahl der Sätze in jedem Exercise.

Wenn wir nun WorkoutSession initialisieren, wird duration_minutes dynamisch um drei Minuten für jeden Satz in jeder Übung erhöht.

# Adding an exercise with three sets
hiit_friday = WorkoutSession([Exercise("Diamond push-ups", 10, 3)])

hiit_friday.duration_minutes
9

Wenn du ein Feld definieren willst, das von anderen Feldern deiner Datenklasse abhängt, kannst du die __post_init__ Logik verwenden.

Unveränderlichkeit in Datenklassen

Unsere WorkoutSession Datenklasse ist fast fertig; sie muss nur noch geschützt werden. Im Moment kann es ziemlich leicht durcheinander gebracht werden:

hiit_friday.duration_minutes = 1000

hiit_friday.duration_minutes
1000

del hiit_friday.exercises

Wir wollen alle Felder unserer Klassen schützen, damit sie nur in der von uns gewünschten Weise geändert werden können. Um dies zu erreichen, bietet der @dataclass Dekorator ein praktisches frozen Argument:

@dataclass(frozen=True)
class FrozenExercise:
   name: str
   reps: int
   sets: int
   weight: int | float = 0


ex1 = FrozenExercise("Muscle-ups", 5, 3)

Wenn wir jetzt ein Feld ändern wollen, erhalten wir eine Fehlermeldung:

ex1.sets = 5
FrozenInstanceError: cannot assign to field 'sets'

Wenn du frozen auf True setzt, werden automatisch die Methoden __deleteattr__ und __setattr__ für jedes Feld hinzugefügt, damit sie nach der Initialisierung vor dem Löschen oder Aktualisieren geschützt sind. Außerdem können andere keine neuen Felder mehr hinzufügen:

ex1.new_field = 10
FrozenInstanceError: cannot assign to field 'new_field'

Diese Funktionalität würde Dutzende von Codezeilen umfassen, wenn wir es mit traditionellen Klassen zu tun hätten.

Beachte aber bitte, dass wir unsere Klassen nicht wirklich unveränderlich machen können. Schreiben wir zum Beispiel die WorkoutSession um, indem wir frozen auf True setzen:

@dataclass(frozen=True)
class ImmutableWorkoutSession:
   exercises: List[Exercise] = field(default_factory=create_warmup)
   duration_minutes: int = 5


session1 = ImmutableWorkoutSession()

Wie erwartet, können wir die Liste der Übungen nicht direkt ändern:

session1.exercises = [Exercise()]

exercises ist jedoch eine Liste, die vollständig veränderbar ist, sodass die folgende Operation möglich ist:

# Ändern eines der Elemente in einer Liste

# Changing one of the elements in a list
session1.exercises[1] = FrozenExercise("Totally new exercise", 5, 5)

print(session1)

ImmutableWorkoutSession(exercises=[Exercise(name='Jumping jacks', reps=30, sets=1, weight=0), FrozenExercise(name='Totally new exercise', reps=5, sets=5, weight=0), Exercise(name='High jumps', reps=20, sets=1, weight=0)], duration_minutes=5)

Zum Schutz vor versehentlichen Änderungen wird daher empfohlen, unveränderliche Objekte wie Tupel für Feldwerte zu verwenden.

Vererbung in Datenklassen

Ein letzter Punkt, den wir behandeln werden, ist die Reihenfolge der Felder in Eltern- und Kindklassen.

Da Datenklassen reguläre Klassen sind, funktioniert die Vererbung wie üblich:

@dataclass(frozen=True)
class ImmutableWorkoutSession:
   exercises: List[Exercise] = field(default_factory=create_warmup)
   duration_minutes: int = 5


@dataclass(frozen=True)
class CardioWorkoutSession(ImmutableWorkoutSession):
   pass

Da aber das letzte Feld in der übergeordneten Klasse (ImmutableWorkoutSession) einen Standardwert hat, müssen alle Felder in den untergeordneten Klassen Standardwerte haben.

Dies ist zum Beispiel nicht erlaubt:

@dataclass(frozen=True)
class ImmutableWorkoutSession:
   exercises: List[Exercise] = field(default_factory=create_warmup)
   duration_minutes: int = 5


@dataclass(frozen=True)
class CardioWorkoutSession(ImmutableWorkoutSession):
   intensity_level: str  # Not allowed, must have a default

TypeError: non-default argument 'intensity_level' follows default argument

Nachteile von Datenklassen und weitere Ressourcen

Die Datenklassen wurden seit Python 3.7 stetig verbessert (sie waren von Anfang an großartig) und decken viele Anwendungsfälle ab, in denen du vielleicht Klassen schreiben musst. In den folgenden Szenarien können sie jedoch nachteilig sein:

  • Benutzerdefinierte __init__ Methoden
  • Benutzerdefinierte __new__ Methoden
  • Verschiedene Vererbungsmuster

Und viele mehr, wie in diesem tollen Reddit-Thread diskutiert. Wenn du eine detailliertere Begründung dafür suchst, warum Datenklassen eingeführt wurden und warum sie kein einfacher Ersatz für normale Klassendefinitionen sind, lies PEP 557.

Wenn du dich für objektorientierte Programmierung im Allgemeinen interessierst, ist dies ein Kurs, mit dem du deine Reise fortsetzen kannst:

Im Grunde genommen sind Datenklassen ausgefeiltere Strukturen, um Daten effizienter zu speichern und abzurufen. Python verfügt jedoch über viele andere Datenstrukturen, die diese Aufgabe mehr oder weniger auf ähnliche Weise erfüllen. Im letzten Kapitel des Kurses "Datentypen für die Datenwissenschaft" erfährst du zum Beispiel mehr über Zähler, defaultdicts und namedtuples.


Bex Tuychiev's photo
Author
Bex Tuychiev
LinkedIn

Ich bin ein Data Science Content Creator mit über 2 Jahren Erfahrung und einem der größten Follower auf Medium. Ich schreibe gerne ausführliche Artikel über KI und ML mit einem etwas sarkastischen Stil, denn man muss etwas tun, damit sie nicht so langweilig sind. Ich habe mehr als 130 Artikel verfasst und einen DataCamp-Kurs gemacht, ein weiterer ist in Vorbereitung. Meine Inhalte wurden von über 5 Millionen Augenpaaren gesehen, von denen 20.000 zu Followern auf Medium und LinkedIn wurden. 

Themen

Weiter Python lernen

Kurs

Intermediate Python

4 hr
1.2M
Level up your data science skills by creating visualizations using Matplotlib and manipulating DataFrames with pandas.
Siehe DetailsRight Arrow
Kurs starten
Mehr anzeigenRight Arrow
Verwandt

Der Blog

Lehrer/innen und Schüler/innen erhalten das Premium DataCamp kostenlos für ihre gesamte akademische Laufbahn

Keine Hacks, keine Tricks. Schüler/innen und Lehrer/innen, lest weiter, um zu erfahren, wie ihr die Datenerziehung, die euch zusteht, kostenlos bekommen könnt.
Nathaniel Taylor-Leach's photo

Nathaniel Taylor-Leach

4 Min.

Der Blog

2022-2023 DataCamp Classrooms Jahresbericht

Zu Beginn des neuen Schuljahres ist DataCamp Classrooms motivierter denn je, das Lernen mit Daten zu demokratisieren. In den letzten 12 Monaten sind über 7.650 neue Klassenzimmer hinzugekommen.
Nathaniel Taylor-Leach's photo

Nathaniel Taylor-Leach

8 Min.

Der Blog

Die 20 besten Snowflake-Interview-Fragen für alle Niveaus

Bist du gerade auf der Suche nach einem Job, der Snowflake nutzt? Bereite dich mit diesen 20 besten Snowflake-Interview-Fragen vor, damit du den Job bekommst!
Nisha Arya Ahmed's photo

Nisha Arya Ahmed

20 Min.

Der Blog

Q2 2023 DataCamp Donates Digest

DataCamp Donates hat im zweiten Quartal 2023 über 20.000 Stipendien an unsere gemeinnützigen Partner vergeben. Erfahre, wie fleißige benachteiligte Lernende diese Chancen in lebensverändernde berufliche Erfolge verwandelt haben.
Nathaniel Taylor-Leach's photo

Nathaniel Taylor-Leach

Der Blog

Die 32 besten AWS-Interview-Fragen und Antworten für 2024

Ein kompletter Leitfaden zur Erkundung der grundlegenden, mittleren und fortgeschrittenen AWS-Interview-Fragen, zusammen mit Fragen, die auf realen Situationen basieren. Es deckt alle Bereiche ab und sorgt so für eine abgerundete Vorbereitungsstrategie.
Zoumana Keita 's photo

Zoumana Keita

30 Min.

Der Blog

Top 30 Generative KI Interview Fragen und Antworten für 2024

Dieser Blog bietet eine umfassende Sammlung von Fragen und Antworten zu generativen KI-Interviews, die von grundlegenden Konzepten bis hin zu fortgeschrittenen Themen reichen.
Hesam Sheikh Hassani's photo

Hesam Sheikh Hassani

15 Min.

Mehr anzeigenMehr anzeigen