Zurück zum Blog

Umstieg von Python auf Go: Was Python-Entwickler wissen sollten

Du kommst von Python zu Go? Die Syntax ist der einfache Teil. Hier sind die echten Umstellungen im Denken, von Fehlern als Werten bis zu Goroutines, dazu ein Cheat Sheet und ein ehrlicher Blick darauf, was du vermissen wirst.

Umstieg von Python auf Go: Was Python-Entwickler wissen sollten

Die gesamte Syntax von Go kannst du an einem Nachmittag durchlesen, und wenn du schon Python schreibst, wird dir das meiste bekannt vorkommen. Diese Vertrautheit täuscht. Neue Keywords lernst du schnell. Das Schwierige am Umstieg auf Go ist, eine Handvoll Python-Gewohnheiten abzulegen, die Go nicht unterstützt. Go hat keine Exceptions zum Abfangen, keine Klassen zum Erben, keine List Comprehensions und keinen Interpreter, in den du mal eben springen kannst. Stattdessen bekommst du explizite Fehlerwerte, Structs mit Interfaces, Goroutines und einen Compiler, der sich beschwert, bevor dein Code überhaupt läuft. Dieser Artikel behandelt die Umstellungen, die darüber entscheiden, ob sich dein erster Monat mit Go wie eine Erleichterung oder wie ein Kampf anfühlt.

Kurzfassung

  • Go-Entwickler sind zufrieden mit der Sprache. 91 % der Befragten sagten, sie seien mit Go zufrieden, und etwa zwei Drittel waren „sehr zufrieden“, das stärkste Ergebnis in Googles offizieller Umfrage (Go Developer Survey 2025).
  • Die Idee hinter der größten Umstellung in Go nutzt du schon. 88 % der Python-Entwickler sagen, dass sie „immer“ oder „oft“ Type Hints verwenden. Statische Typisierung ist also eine Gewohnheit, mit der du bereits angefangen hast (Typed Python 2024 Survey, Meta).
  • Teams, die migriert haben, sahen echte Verbesserungen. Als Khan Academy sein Python-Backend in Go neu geschrieben hat, sank die Renderzeit einer Seite von etwa 28 Sekunden auf rund 4 Sekunden (Khan Academy Engineering). Mit dem Wechsel zu einem Kommentar-Service in Go hat Reddit die p99-Schreiblatenz halbiert (InfoQ).
  • Python ist immer noch größer, und das ist in Ordnung. Python wird von 54,8 % der professionellen Entwickler genutzt, Go von 17,4 %, und bei Daten- und KI-Arbeit dominiert Python (Stack Overflow 2025). Go tritt in einem engeren Bereich an: latenzkritische Backends, APIs und CLIs.

Inhaltsverzeichnis

Sollten Python-Entwickler Go lernen?

Ja, besonders wenn sich deine Arbeit in Richtung Backend-Services, APIs, Infrastruktur oder Kommandozeilen-Tools bewegt. Go-Entwickler berichten von der höchsten Zufriedenheit unter allen großen Sprachen: In Googles offizieller Umfrage sind 91 % zufrieden und fast zwei Drittel „sehr zufrieden“ (Go Developer Survey 2025). Diese Zufriedenheit kommt eher daher, dass Go vorhersehbar ist, als daher, dass es clever wäre. Vorhersehbarkeit ist das, was sich die meisten Python-Entwickler wünschen, sobald eine Codebase über ein paar tausend Zeilen hinauswächst.

Der Umstieg geht schnell, weil sich so viel übertragen lässt. Du denkst schon in Funktionen, Slices und Maps. Du teilst deine Arbeit schon in Packages auf und schreibst Tests. Wie du an Probleme herangehst, bleibt gleich. Was sich ändert, ist, wie streng dich die Sprache an deine Entscheidungen bindet. Go gibt einen Teil der Flexibilität von Python im Tausch gegen Garantien auf, und in diesem Artikel geht es größtenteils darum, wo sich das bemerkbar macht.

Warum Teams von Python zu Go wechseln

Teams wechseln meistens aus demselben Grund: Ein Python-Service, der schnell geschrieben war, wurde im Betrieb zu langsam oder zu teuer. Als Khan Academy seinen Server in Go neu geschrieben hat, wurde eine Klassenliste mit 1.000 Schülern, deren Laden in Python etwa 28 Sekunden dauerte, in rund 4 Sekunden gerendert. Das ist fast eine 7-fache Verbesserung. Die Warnungen wegen Datastore-Contention fielen von rund 100 pro Stunde auf nahezu null (Khan Academy Engineering).

Reddit hat Ähnliches erlebt. Nachdem Reddit 2025 das Backend für seine Kommentarbäume auf einen Go-Microservice umgestellt hatte, lag die p99-Schreiblatenz bei der Hälfte des alten Python-Systems, das gelegentlich Ausreißer von bis zu 15 Sekunden hatte (InfoQ).

Lovable, der KI-App-Builder, ist das eindrucksvollste aktuelle Beispiel. Das Unternehmen hat sein gesamtes Backend von Python nach Go umgeschrieben, 42.000 Zeilen Code. Die Zahl der Serverinstanzen sank von 200 auf 10, Deployments dauerten statt 15 nur noch 3 Minuten, und Requests wurden im Schnitt 12 % schneller (Lovable Engineering). Den Ausschlag für das Umschreiben gab die Nebenläufigkeit. Eine einzige Chat-Anfrage bei Lovable kann sich in mehr als 50 HTTP-Aufrufe auffächern. Go bewältigt diese Art paralleler Last nativ, während der GIL von Python sie umständlich macht.

In jedem dieser Fälle leistet die kompilierte, statisch typisierte Runtime von Go mit Garbage Collection mehr Arbeit pro Server. Derselbe Traffic kostet dadurch weniger und verhält sich unter Last stabiler.

Statische Typisierung: Du bist schon auf halbem Weg

Python-Entwickler fürchten statische Typisierung meist mehr als alles andere an Go und gewöhnen sich trotzdem am schnellsten daran, weil die meisten sich längst freiwillig dafür entschieden haben. In einer Umfrage von 2024 gaben 88 % der Python-Entwickler an, „immer“ oder „oft“ Type Hints zu verwenden, wobei mypy und Pydantic die gängigsten Tools waren (Typed Python 2024 Survey, Meta). Wenn du Funktionssignaturen annotierst und in der CI einen Type Checker laufen lässt, hast du die Grundidee von Go bereits akzeptiert. Go macht die Prüfung verpflichtend und legt sie in den Compiler statt in ein optionales Tool.

Der praktische Unterschied liegt darin, wann du merkst, dass du falsch lagst. In Python zeigt sich ein Typfehler erst zur Laufzeit, oft in Produktion, manchmal Stunden nach dem Deployment. In Go stoppt derselbe Fehler den Build. Du kannst keinen String übergeben, wo ein int erwartet wird, und du kannst keine Variable ungenutzt lassen. Ein err, das du zuweist und nie prüfst, kompiliert also nicht. Für Einsteiger fühlt sich das wie Nörgelei an. Wenn du schon mal um 2 Uhr nachts einen NoneType has no attribute-Fehler debuggt hast, fühlt es sich eher wie ein Sicherheitsnetz an.

So sieht das aus. Die Go-Version kompiliert nicht, sobald Total den falschen Typ hat, während eine Python-Version einfach hoffen würde, dass der Aufrufer eine Zahl übergeben hat:

example.gogo
type Order struct {
	ID    string
	Total int // cents, never a float, never a string
}

func discount(o Order, pct int) int {
	return o.Total - (o.Total * pct / 100)
}

Type Inference sorgt dafür, dass das nicht zu wortreich wird. Mit := ermittelt Go den Typ aus dem Wert, du schreibst also count := 0, statt überall int auszuschreiben. Du behältst die Sicherheit von Deklarationen und fast die ganze Kürze von Python.

Fehler sind Werte, keine Exceptions

Das ist die größte Umstellung, und sie wird sich etwa eine Woche lang seltsam anfühlen. Go hat kein try, kein except und keine Exceptions im Python-Sinn. Funktionen, die fehlschlagen können, geben als letzten Wert einen error zurück, und du prüfst ihn direkt dort, wo du den Aufruf gemacht hast. Nichts wird den Stack hinaufgeworfen, um irgendwo weit entfernt abgefangen zu werden. Du behandelst den Fehler, ignorierst ihn oder reichst ihn weiter, und zwar in der Zeile, in der er aufgetreten ist.

Dieses Idiom wirst du tausende Male tippen:

example.gogo
resp, err := http.Get(url)
if err != nil {
	return fmt.Errorf("fetch %s: %w", url, err)
}
defer resp.Body.Close()

Python-Entwickler mögen if err != nil anfangs oft nicht. Drei Zeilen Fehlerbehandlung nach jedem Aufruf wirken unruhig, verglichen mit einem einzigen try um einen ganzen Block. Die Wiederholung ist aber Absicht. Du siehst jeden Fehlerpfad der Funktion, wenn du sie von oben nach unten liest, ohne unsichtbare Sprünge zu einem entfernten Handler. Das Verb %w wrappt den ursprünglichen Fehler, damit Aufrufer ihn weiterhin untersuchen können. Das ist die Go-Version einer Exception-Kette.

Diese Gewohnheit nimmst du auch mit zurück zu Python. Wenn du erst mal gewohnt bist, Fehler an der Aufrufstelle zu behandeln, wirkt ein breiter except Exception-Block wie das, was er ist: eine Methode, Informationen darüber zu verlieren, was schiefgelaufen ist.

Nebenläufigkeit: Goroutines vs. GIL

Bei der Nebenläufigkeit hört Go auf, „Python mit Typen“ zu sein, und wird zu einem anderen Werkzeug. Der Global Interpreter Lock von CPython lässt immer nur einen Thread Python-Bytecode ausführen. Threads können CPU-lastige Arbeit deshalb nicht parallel erledigen. Free-threaded Builds ohne GIL kamen mit Python 3.13 unter PEP 703 als experimentelles Feature, sie sind aber nicht der Standard, und das Ökosystem zieht noch nach (Python-Dokumentation). Vorerst bedeutet das Skalieren von CPU-lastigem Python meist, mehrere Prozesse laufen zu lassen und die Kosten für Speicher und Koordination zu tragen, die damit einhergehen.

Go wurde von Anfang an um Nebenläufigkeit herum entworfen. Eine Goroutine ist ein Funktionsaufruf mit go davor, und die Runtime verteilt Tausende davon auf deine CPU-Kerne, ohne dass ein GIL im Weg steht. Goroutines kommunizieren über Channels statt über gemeinsamen Speicher. Hundert nebenläufige Fetches zu starten braucht so viel Code:

example.gogo
results := make(chan string)
for _, url := range urls {
	go func() {
		resp, err := http.Get(url)
		if err != nil {
			results <- "error: " + url
			return
		}
		defer resp.Body.Close()
		results <- url + " ok"
	}()
}
for range urls {
	fmt.Println(<-results)
}

Wenn du schon mit asyncio gearbeitet hast, verstehst du das Ziel bereits. Go erreicht es, ohne deinen Code in „gefärbte“ async- und sync-Hälften aufzuspalten. Jede Funktion kann in einer Goroutine laufen. Du schreibst kein await, startest keine Event Loop und suchst nicht nach Async-Versionen deiner Bibliotheken. Das erklärt zu einem großen Teil, warum Go-Services unter Last durchhalten: Das Nebenläufigkeitsmodell von Go ist fest in die Sprache eingebaut und wurde nicht nachträglich hinzugefügt.

Structs und Interfaces statt Klassen und Vererbung

Go hat keine Klassen und keine Vererbung, was Leute mehr überrascht, als es sollte. Daten modellierst du mit einem struct, und Verhalten gibst du ihm, indem du Methoden daran hängst. Nichts übergibt self implizit, es gibt kein __init__ und keine Basisklasse, die du erweitern kannst. Wo Python eine Klassenhierarchie nutzen würde, nutzt Go Komposition. Du bettest ein Struct in ein anderes ein, um dessen Felder und Methoden wiederzuverwenden, statt von einer Elternklasse zu erben.

Bei Interfaces wird Go elegant, und sie funktionieren nicht so, wie du es erwarten würdest. Ein Typ erfüllt ein Interface einfach dadurch, dass er die richtigen Methoden hat. Es gibt kein implements-Keyword und keinen Registrierungsschritt. Wenn dein Struct eine Methode Read([]byte) (int, error) hat, ist es ein io.Reader. Das ist das Duck Typing, das du aus Python kennst, nur zur Compile-Zeit geprüft:

example.gogo
type Notifier interface {
	Notify(msg string) error
}

type SlackClient struct{ webhook string }

func (s SlackClient) Notify(msg string) error {
	// any type with this method is a Notifier, automatically
	return post(s.webhook, msg)
}

Gedanklich wechselst du von „Was ist dieses Objekt?“ zu „Was kann dieses Objekt?“. Deine Interfaces werden kleiner sein, als du erwartest, oft mit nur einer einzigen Methode, und du definierst sie neben dem Code, der sie nutzt, nicht neben dem Typ, der sie erfüllt. Diese Umkehrung braucht ein paar Tage, bis sie sich natürlich anfühlt. Danach gehört sie meist zu den Dingen, die du am meisten vermisst, wenn du zu Python zurückwechselst.

Weniger Magie, mehr Explizitheit

Python belohnt Cleverness. Mit Decorators, Metaklassen, Dunder-Methoden, Monkey-Patching und dynamischem Attributzugriff kannst du die Sprache verbiegen, wie du willst. Go lässt fast alles davon bewusst weg. Es hat keine Decorators, keine Metaklassen, kein Operator Overloading und keine Möglichkeit, einem Typ, der dir nicht gehört, eine Methode hinzuzufügen. Du kannst fast immer erkennen, was eine Zeile macht, ohne von etwas zu wissen, das woanders passiert.

Am ersten Tag fühlt sich das einschränkend an, im zweiten Monat befreiend. Eine fremde Go-Codebase zu lesen ist größtenteils einfach nur Lesen, weil nichts Verstecktes hinter den Kulissen das Verhalten umschreibt. Der Nachteil: Go kann wortreicher sein. Manchmal schreibst du eine Schleife, wo Python dir eine einzeilige Comprehension geben würde. Die Go-Community hält das für einen fairen Preis. Die Designer der Sprache haben darauf gesetzt, dass Code weit öfter gelesen als geschrieben wird, also haben sie für die Lesenden optimiert.

Das Python-zu-Go-Cheat-Sheet

Für die meisten alltäglichen Python-Konstrukte gibt es ein direktes Gegenstück in Go. Halte diese Tabelle in deiner ersten Woche offen. Die Namen ändern sich und die Zeichensetzung wird strenger, aber die Konzepte lassen sich fast eins zu eins übertragen.

PythonGoHinweis
x = 5x := 5:= leitet den Typ ab
def f(a, b):func f(a, b int) int {Typen werden deklariert, auch der Rückgabetyp
list[]T (Slice)Typisiert, wächst aber mit append wie eine Liste
dictmap[K]VKeys und Values sind typisiert
for x in items:for _, x := range items {range liefert Index und Wert
try / exceptif err != nil {Fehler werden zurückgegeben, nicht geworfen
class Foo:type Foo struct {Dazu Methoden und Interfaces
NonenilFür Pointer, Slices, Maps, Interfaces
f"{name}"fmt.Sprintf("%s", name)Keine f-Strings, nutze das Package fmt
pip installgo getModule sind in die Toolchain eingebaut
# comment// commentGleiche Idee, anderes Zeichen

Die größten optischen Veränderungen sind die geschweiften Klammern und die fehlenden Doppelpunkte. Weil Go statisch typisiert ist, erwischt dich der Compiler in dem Moment, in dem eine Übertragung falsch ist. Nutze das. Den Build scheitern zu lassen und die Fehlermeldung zu lesen ist der schnellste Weg, die Zuordnung zu lernen.

Tooling: ein Binary, ein Formatter, eingebaute Tests

Das Tooling von Go ist einer der am meisten unterschätzten Gründe, warum Leute bei Go bleiben. Es gibt keine auseinanderdriftende requirements.txt, kein virtuelles Environment zum Aktivieren und keinen separaten Formatter, Linter und Test Runner, die du miteinander verdrahten musst. Der Befehl go deckt all das ab und kommt mit einer einzigen Installation. Beim Kompilieren entsteht ein einzelnes statisches Binary ohne Interpreter oder Abhängigkeiten, die du mitliefern musst. Deployment heißt deshalb oft einfach, eine Datei auf den Server zu kopieren.

Das fällt dir zuerst auf:

  • go build erzeugt ein einziges Binary. Auf der Zielmaschine muss kein Python installiert sein, du packst keinen Interpreter mit, und beim Deployment tauchen keine Probleme mit Abhängigkeiten auf.
  • gofmt beendet Diskussionen über Formatierung. Go hat einen kanonischen Stil und ein Tool, das ihn durchsetzt, also dreht sich kein Code Review je um Whitespace. Denk an black, nur eingebaut und von allen genutzt.
  • go test gehört zur Toolchain. Tests liegen in _test.go-Dateien neben deinem Code und laufen mit einem Befehl. Du musst pytest weder installieren noch konfigurieren.
  • go vet und das Modulsystem sind eingebaut. Abhängigkeiten werden in go.mod versioniert und mit go get geholt, und Builds sind ohne Drittanbieter-Tool reproduzierbar.

Nach Jahren, in denen du Python-Umgebungen verwaltet hast, ist es jeden Tag eine kleine Erleichterung, gar keine mehr verwalten zu müssen. Du schreibst Code, führst go build aus und lieferst das Ergebnis aus.

Was du an Python vermissen wirst

Die Strenge von Go hat echte Kosten, und du solltest wissen, was du aufgibst. Am meisten wirst du die REPL vermissen. Go hat keinen interaktiven Interpreter, mit dem du eine Bibliothek ausprobieren oder ein Snippet testen kannst. Zum Ausprobieren schreibst du also eine kleine main und führst sie aus. Du wirst List und Dict Comprehensions vermissen, weil Go dich die Schleife jedes Mal ausschreiben lässt. Und ab und zu wirst du die Flexibilität von Python vermissen, also die Art, wie du Daten spontan umformen kannst, ohne vorher einen Typ zu deklarieren.

Die Lücke im Ökosystem wiegt schwerer, weil sie deine Karriere betrifft und nicht nur deine Bequemlichkeit. Python beherrscht Data Science, Machine Learning und wissenschaftliches Rechnen. Das sieht man daran, womit Python-Entwickler ihre Zeit verbringen: Datenexploration, Webentwicklung und ML führen die Liste an (JetBrains State of Python 2025). Wenn dein Job darin besteht, Modelle zu trainieren oder mit Dataframes zu hantieren, wird Go Python dort nicht ersetzen und versucht es auch nicht. Es ist sinnvoller, Go dazuzunehmen, als zu tauschen. Behalte Python für Daten- und KI-Arbeit und nutze Go, wenn du einen schnellen, zuverlässigen Service, eine CLI oder Infrastruktur-Tooling brauchst. Das passt zu dem, was Go-Entwickler bauen: 75 % bauen API- oder RPC-Services und 62 % bauen Kommandozeilen-Tools (Go Developer Survey 2024 H2).

So gelingt der Umstieg

Als Python-Entwickler lernst du Go am schnellsten, wenn du aufhörst, über die Unterschiede zu lesen, und ihnen in echtem Code begegnest. Die Konzepte verstehst du schon. Was du brauchst, ist Wiederholung: genug kleine, automatisch bewertete Übungen, bis dich die Syntax und der Rhythmus der Fehlerbehandlung kein bewusstes Nachdenken mehr kosten. Der Wechsel von Exceptions zu Fehlern als Werten sitzt erst, wenn du if err != nil ein paar hundert Mal in echten Programmen getippt hast.

Schau nicht einfach passiv Tutorials. Anderen beim Schreiben von Go zuzusehen bringt dir sehr wenig darüber bei, wie du es selbst schreibst, und es ist besonders verlockend, wenn die Sprache so einfach aussieht. Schreib jeden Tag ein bisschen Go, hol dir Feedback, das dir sofort sagt, wenn du falsch liegst, und bau etwas Echtes, sobald du eine Funktion schreiben kannst, ohne nachzuschlagen. Eine kleine JSON-API, eine CLI, die eine Datei umformatiert, oder ein Programm, das einen anderen Service aufruft und die Antwort umbaut, sind in Go alles kurze Projekte, und sie nutzen die Muster, auf die du dich im Job stützen wirst.

Häufig gestellte Fragen

Ist Go schwerer zu lernen als Python?

Die Syntax nicht. Go hat nur 25 Keywords und einen einzigen verbindlichen Formatierungsstil, du musst dir also weniger merken als in Python. Schwieriger ist die Disziplin: Fehler als Werte zu behandeln und Typen zu deklarieren kostet am Anfang mehr Aufwand. Python-Entwickler, die schon Type Hints nutzen, und das sind 88 % von ihnen, haben einen echten Vorsprung (Typed Python 2024 Survey, Meta).

Warum beherrscht Go Nebenläufigkeit besser als Python?

Der Global Interpreter Lock von CPython lässt immer nur einen Thread Bytecode ausführen, deshalb braucht parallele CPU-Arbeit mehrere Prozesse (Python-Dokumentation). Goroutines laufen ohne GIL auf allen Kernen, kommunizieren über Channels und brauchen kein separates Async-Ökosystem. Dieses Modell ist ein wichtiger Grund, warum Go-Services unter Last stabiler bleiben.

Wie lange braucht ein Python-Entwickler, um Go zu lernen?

Die grundlegende Syntax hast du schnell drauf, weil sich Funktionen, Slices, Maps und Packages direkt aus Python übertragen lassen. Go-Code zu schreiben, den ein Team im Code Review freigeben würde, dauert länger. Was Go idiomatisch macht, ist das, was Python dir nie beigebracht hat: Fehler als Werte, kleine Interfaces, Komposition statt Vererbung, Goroutines und Channels sowie die Konventionen der Standardbibliothek. Die meisten Entwickler brauchen ein paar konzentrierte Monate mit echten Projekten, bis das sitzt. Tutorials zu lesen bringt dich nicht von „Ich kann Go lesen“ zu „Ich schreibe idiomatisches Go“. Strukturierte, praxisnahe Übung schafft das, also Dinge bauen und Feedback auf echte Übungen bekommen.

Brauche ich für die Backend-Entwicklung noch Python, wenn ich Go lerne?

Nein. Für Backend-Arbeit deckt Go für sich allein alles ab. Die Standardbibliothek enthält HTTP-Server, JSON, SQL-Treiber und Nebenläufigkeit ohne Framework, du kannst also Services für die Produktion komplett in Go bauen und ausliefern. Go kompiliert zu einem einzelnen statischen Binary ohne Runtime, die installiert werden muss, startet schnell und bewältigt Workloads mit hoher Nebenläufigkeit über Goroutines. Deshalb läuft so viel moderne Infrastruktur auf Go. Python bleibt bei Data Science und Machine Learning der Standard, aber das ist ein anderer Job. Für APIs, Microservices, CLIs und Infrastruktur-Tooling reicht Go aus.

Fang heute an, Go zu schreiben

Deine Python-Erfahrung hilft dir hier. Du denkst bereits in den richtigen Formen. Was bleibt, ist eine kleine Zahl neuer Regeln zu verinnerlichen, und das schaffst du, indem du Go schreibst. Fehlerbehandlung, Interfaces und Goroutines sind nicht schwer, aber jedes davon braucht Übung, bis es sich natürlich anfühlt.

Dafür ist LevelUpGo gebaut. Jede Lektion ist eine Übung im Browser, die deinen Code mit der aktuellen Go-Toolchain ausführt und sofort bewertet. So schreibst du vom ersten Tag an echtes Go.

Ein möglicher Weg für Python-Entwickler:

  • Starte mit den Grundlagen. Der Kurs Go Fundamentals führt dich von deinem ersten Programm bis zu Funktionen, Typen und Structs und übt das Muster der Fehlerbehandlung von Anfang an. Der Einstieg ist kostenlos, eine Kreditkarte brauchst du nicht.
  • Lerne das eine Modell, das wirklich neu ist. Der Kurs Go Concurrency Fundamentals bringt dir Goroutines, Channels und select bei. Python hat dafür kein direktes Gegenstück, und es ist der Teil, der sich unter Last am meisten auszahlt.
  • Lerne, Go auf die Go-Art zu schreiben. Der Lernpfad Clean Go Code behandelt die Idiome, die Benennung und die Fehlerbehandlung, durch die sich dein Go wie Go liest und nicht wie Python mit geschweiften Klammern.

Starte mit dem kostenlosen Kurs, schreib jeden Tag ein bisschen Go und halte deinen Streak am Laufen.

Schreib Go wie ein Senior Engineer

Interaktive Lektionen im Browser. Die ersten sind kostenlos.

Kostenlose Lektion testenOder kostenloses Konto erstellen