Wat betreft gemak voor ontwikkelaars en snelle ontwikkeling zijn er twee programmeertalen die met kop en schouders boven de rest uitsteken: Python en Go. Python is een graag geziene gast bij ontwikkeling die zich bezighoudt met scripting, devops, machine learning en testen, terwijl Go wordt gebruikt voor een nieuwe golf van containergebaseerde cloud-native toepassingen.
Soms ligt de keus voor de hand: Python voor een rijk ecosyseem, Go voor snelle uitvoeringssnelheid. Maar soms is het wat subtieler en niet meteen duidelijk. In dit artikel lopen we door de verschillen en belichten we de plus- en minpunten om je te helpen een geïnformeerde keuze te maken als je een taak wilt gaan uitvoeren.
Go vs. Python: Ontwikkelgemak
Python en Go hebben beide een reputatie van eenvoud. Ze hebben allebei een simpele en makkelijke syntaxis en een featureset die klein en makkelijk te onthouden is.
Python en Go hebben allebei een korte cyclus van schrijven-compileren-draaien. Er is geen compilatiefase in Python - het heeft een interpreter - dus scripts worden vrijwel direct uitgevoerd. Go compileert vooraf, maar de compilatiefase is een stuk sneller dan bij talen als C++. Go voelt meer als een scripttaal dan als een taal die vooraf wordt gecompileerd.
Python gebruikt dynamische typering, wat het makkelijk maakt om snel prototypes van applicaties te maken. Elementen typeren met omschrijvingen is optioneel en kan worden toegevoegd om ervoor te zorgen dat het programma correct interpreteert (wat een goed idee is bij grote projecten) maar het is niet vereist. Grote codebases worden echter onhandelbaar als je geen types aangeeft.
In het geval van Go is typering strikt, maar wordt in de meeste gevallen makkelijk afgeleid, dus het is minder omslachtig. Dat betekent ook dat grotere codebases eenvoudiger zijn te beheren van meet af aan, omdat Go-ontwikkelaars de traditie van het gebruik van typeringen in de vingers hebben. De keerzijde is dat Go genericiteit ontbeert, dus code die korter zou kunnen worden omschreven in andere talen - waaronder Python - worden wat uitgebreider en veel omschrijvender in Go.
Go vs. Python: Snelheid van de runtime
Als er één gebied is waar Go met gemak Python verslaat, is het de snelheid. Go draait veel sneller dan Python, zelfs zonder optimalisaties van de ontwikkelaars. Go compileert direct naar native machinetaal, terwijl de runtime van Python lastiger is om te optimaliseren voor snelheid.
Dat neemt niet weg dat Python voor doorsnee taken snel genoeg is, dus het is de moeite waard om van je use-case een benchmark te maken van een Python-implementatie. De prestatie-intensiefste taken waar Python voor wordt gebruikt worden niet uitgevoerd in Python zelf, maar via library's die zijn geschreven in C of C++. Ook de PyPy-runtime, een alternatief van de traditionelere CPython-runtime kan een snelheidboost leveren aan applicaties als webservers, zelfs op plekken waar Pythons scripting-achtige elementen zwaar worden gebruikt.
Go vs. Python: Uitrol
Go was vanaf zijn begin ontworpen om gecompileerde apps meteen uit te kunnen rollen als stand-alone binary's voor meerdere platforms. Dat staat in schril contrast met Python; ontworpen als scripttaal is de Python-runtime vereist om programma's te draaien.
Python heeft geen native oplossing om een script als stand-alone executable te draaien, maar je kunt naar een third party-library als PyInstaller stappen voor deze functionaliteit. Ook containeroplossingen als Docker maken het eenvoudiger om een Python-app samen met de runtime te verpakken.
Go vs. Python: Projectmanagement
Nog iets wat meteen in Go zit: moderne softwaremanagement. Snelle opdrachten in de command-line maken een nieuwe Go-projectrepo en beheren de dependency's. We moeten hierbij opmerken dat Go niet altijd de beste ondersteuning heeft geleverd voor dependency's en reproduceerbare builds, maar het module-systeem, dat in Go 1.11 werd geïntroduceerd levert een gedeeld mechanisme om te werken met verschillende versies van library's.
Python heeft op een aantal gebieden precies het tegenovergestelde probleem: een breed scala aan projectbeheer- en versietools levert verwarring op over welke methoden het beste zijn voor een bepaalde taak. De positieve kant is dat je ook flexibel genoeg bent dat je niet hoeft te werken op de manier die wordt afgedwongen door specifieke tooling.
Go vs. Python: Asynchroon programmeren
Asynchrone operaties - de ene taak uitvoeren terwijl je op een andere wacht - helpen op I/O gerichte code, zoals netwerk-services, efficiënter kunnen draaien.
Go ondersteunt async native in zijn goroutines, een syntaxis-feature. Met goroutines kun je kleine operaties parallel uitvoeren met een native communicatiegegevenstype, channels, om de operaties te synchroniseren. Go heeft ook tooling om per ongeluk verkeerd gebruik van de features te voorkomen: je kunt nog steeds code schrijven met een race-conditie of deadlock, maar het is eenvoudig om de meest gangbare fouten op te vangen.
Python kreeg onlangs ook ondersteuning op taalniveau voor asynchroon gedrag met de keywords async/wait
. Daarvoor was asynchroon programmeren wel mogelijk, maar niet zo duidelijk. Dat betekent dat library-ondersteuning voor modern async-gebruik niet zo geavanceerd is als het had kunnen zijn, omdat het zo'n laatkomer is in de taal. Maar meer library's worden nu aync-compatibel en de versies van Python die het niet hebben raken hun ondersteuning binnenkort kwijt.
Go versus Python: Omgaan met fouten en debugging
De twee talen hebben fundamenteel andere filosofieën over hoe ze moeten omgaan met fouten. In Python zijn fouten first-call objecten en ze duiken op wanneer de applicatie een uitzondering tegenkomt. Het maken van een exception is daarmee optioneel en de ontwikkelaar moet bepalen of deze gevallen worden opgevangen en afgehandeld. Dat betekent een flexibele foutafhandeling die niet elke call rommelig maken met mogelijke uitzonderingen.
In Go werkt het heel anders: elke functie geeft de waarde van de functie zelf en een mogelijk fout-object. Go-programma's omschrijven meestal heel specifiek welke gevallen fouten kunnen opleveren bij de functie zelf, waardoor de afhandeling ervan vooraf duidelijk is. Het nadeel is dat je meer code schrijft.
Go heeft verder panic/recover
om extreme gevallen op te vangen die er niet zouden moeten toe leiden dat het programma vastloopt, maar het is de bedoeling dat je ze niet zo uitgebreid inzet als exceptions in Python. In Go 2.0 zouden wel eens nieuwe methodes kunnen worden toegevoegd die minder omschrijvende code oplevert, maar die revisie is nog lang niet klaar.
Go versus Python: Testen
Niet alle moderne software-ontwikkeling gebruikt unit- en integratietests, maar projecten die dat wel doen, zijn in de regel robuuster. Python en Go bieden beide native mechanismes voor unit-testing. Bij Go is er het native pakket testing
en bij Python is er het framework unittest
.
Bij Go kun je in testing
instellen wat wordt meegenomen, bij Python heb je daar third party-pakket coverage
voor nodig. Aan de andere kant heeft Python heel flexibele ingebouwde testopties - bijvoorbeeld assertions die een heel brede reeks veelvoorkomende gevallen controleert, inclusief opduikende exceptions. Python gebruikt een speciale class om testcode te onderscheiden van applicatiecode, terwijl Go gebruikelijke functies en bestandsnamen hanteert.
Go versus Python: Ecosystemen
Door de jaren heen hebben beide talen een indrukwekkend aantal library's aan third party-software verzameld die de sterke en zwakke punten illustreren.
Python is vaak de go-to voor scripting en automatiseren en wordt ingezet voor het bouwen van web-services en eenvoudige interfaces tussen complexe systemen. Vanwege die laatste toepassing is de taal zo groot geworden in machine learning en data-science: Python maakt het makkelijker om grote, complexe library's en workflows aan elkaar te lijmen die worden gebruikt bij data-analytics en machine learning-modellen.
Bij Go zit het succesverhaal in asynchroon programmeren en de native snelheid ervan. Webservers, netwerkapplicaties, CPU-gebonden microservices en systeemtools zijn allemaal prachtige kandidaten voor Go. De meeste software die moderne, containergebaseerde applicattie-ontwikkeling ondersteunen - inclusief Docker en Kubernetes - zijn geschreven in Go.
Een manier om te kijken naar welke van de twee je nodig hebt is door je te laten informeren door bestaande Python- en Go-projecten die lijken op waar je mee bezig bent. Er is een gerede kans dat veel van wat je probeert te doen al eens is ontwikkeld, dus je kiest niet alleen een taal, maar ook de ondersteunende library's die ervoor bestaan.
Ten slotte is het het vermelden waard dat je niet altijd hoeft te kiezen en de twee naast elkaar kunt gebruiken. Zet Go in voor prestatiegevoelige componenten van je applicatie en gebruik Python-wrappers en -frontends voor ontwikkelgemak.
Reageer
Preview