course

Vad är Zen of Python?
Zen of Python är en samling på nitton aforismer som fungerar som vägledande principer för Pythons design. Det var faktiskt tänkt att vara tjugo aforismer; men Guido van Rossum, skaparen av Python, har fortfarande inte lagt till den sista aforismen enligt Tim Peters avsikt, skaparen av Zen of Python. Guido ska ha sagt att den saknade tjugonde aforismen är ”något bisarrt internskämt av Tim Peters”.
Trots den saknade tjugonde aforismen standardiserades Zen of Python som PEP 20 år 2004 på grund av dess stora inflytande på Pythonprogrammerares utvecklingsprocess. Det är inte obligatoriskt att följa Zen of Python, men det rekommenderas att känna till den och ha den i åtanke. Om du någonsin glömmer lärdomarna kan du enkelt friska upp minnet genom att köra import this i Python-tolken.
>>> import this
The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
I den här artikeln går vi igenom varje lärdom i mer detalj.
#1 Vackert är bättre än fult
Om du är programmerare råder det ingen tvekan om att du är högkompetent. Förmågan att lösa problem med kod är inte lätt, men som Pythonista förväntas ännu mer av dig. Vacker kod är bättre än ful kod. Pythons snabba uppgång i popularitet beror delvis på dess tillgänglighet: den är enkel, läsbar och elegant. Som Pythonutvecklare har du ett ansvar att upprätthålla den pythoniska standarden genom att skriva vacker kod.
Vad är vacker kod? Tja, det är subjektivt – skönheten ligger i betraktarens öga och så vidare. En enkel tumregel för att hålla dig på rätt spår är att skriva ren, läsbar kod som andra utvecklare lätt kan förstå. Till exempel:
"""
Initial code was created by Vishal Sharma
See: https://towardsdatascience.com/the-zen-of-python-a-guide-to-pythons-design-principles-93f3f76d088a
"""
def collatz(num):
if num % 2 == 0:
return num // 2
else:
return 3 * num + 1
number = input("Enter a number: ")
while number != 1:
number = collatz(int(number))
print(number)
"""
Enter a number: 5
16
8
4
2
1
"""
Koden ovan fungerar alldeles utmärkt, men den är inte nödvändigtvis vacker. Vi har en onödig else-sats i vår collatz-funktion som kan tas bort så här:
def collatz(num):
if num % 2 == 0:
return num // 2
return 3 * num + 1
Alltså, när du ställs inför ett scenario där du har två fungerande kodstycken, bör du välja det som är enklare, mer läsbart och lättare att förstå.
#2 Explicit är bättre än implicit
Att förklara en aforism som ”självförklarande” är ett stort misstag – ändå kommer du att se folk göra det. Kärnan i ”explicit är bättre än implicit” är att utförlig kod är att föredra framför indirekt kod. Gör allt du kan för att se till att din kodes funktionalitet inte döljs bakom obskyrt språk. Någon utan förkunskaper om ditt program ska ändå kunna förstå vad som händer i din kod.
#3 Enkelt är bättre än komplext
Du skulle antagligen skratta om din kompis tog fram en högtryckstvätt för att diska efter maten. Det är inte bara en synnerligen fånig lösning, det finns också stor risk att tallrikarna skadas. På samma sätt är det extremt opraktiskt att tillämpa en mycket komplex lösning på ett enkelt programmeringsproblem. Det finns ingen anledning att överkomplicera din lösning, även om du tycker att det får dig att verka smart. Du kan orsaka mer skada än nytta och det uppskattas inte i Python.
Titta på den här funktionen som används för att vända en sträng:
def reverse_string(string):
if len(string) == 1:
return string
else:
return reverse_string(string[1:]) + string[0]
string = "kurtis"
print(reverse_string(string))
"""
sitruk
"""
Koden ovan löser visserligen problemet, men den är onödigt komplex. Om du har bra koll på Python vet du att en sträng kan vändas med indexering.
string = "kurtis"
# annonymous function solution
reverse_string = lambda x: x[::-1]
# function solution
def reverse(string):
return string[::-1]
print(reverse_string(string))
print(reverse(string))
"""
sitruk
sitruk
"""
#4 Komplex är bättre än komplicerad
Att diska med högtryckstvätt är opraktiskt: du kommer bättre undan med en enkel lösning som rinnande vatten. Men tänk om problemet var att rengöra en 4x4 Range Rover? Den föregående aforismen och den här påminner oss om att både enkla och komplexa tekniker kan användas för att lösa ett och samma problem. Att rengöra en 4x4 Range Rover är inte ett enkelt problem, och att försöka använda samma teknik som när du diskar kan fungera men är mer komplicerat än att använda en högtryckstvätt. Alltså bör du föredra enkelhet framför komplexitet, men i situationer där enkelhet är opraktisk är det bättre att välja komplexitet – känn enkelhetens gränser.
#5 Platt är bättre än nästlad
Programmerare älskar att organisera saker i kategorier, underkategorier och under-underkategorier som ett sätt att separera funktionalitet. Även om det kan låta ordningsamt kan en sådan organisering av koden leda till mer förvirring än ordning.
Det är inget fel med att lägga all din kod i en modul på toppnivå: det betyder att du inte behöver göra något i stil med from spam.foo.bar.john.doe import chicken för att komma åt en viss funktionalitet. Ju fler underkategorier du lägger till, desto mer komplicerad blir din kod. Gör allt du kan för att hålla dig till en platt struktur när det är möjligt.
#6 Glest är bättre än kompakt
Programmerare anses vara bland de mest intelligenta människorna, så det finns ingen anledning att understryka din intellekt med överdrivna knep. Det vanligaste du hör är ”hur du gör [någon komplicerad uppgift] på en rad kod.” Ibland är enradare motiverade, men undvik situationer där du offrar läsbarhet för att klämma in all funktionalitet på en rad.
Ta den här kodsnutten som exempel:
"""
Code source Al Sweigart
See: https://inventwithpython.com/blog/author/al-sweigart.html0
"""
print('\n'.join("%i bytes = %i bits which has %i possible values." % (j, j*8, 256**j-1) for j in (1 << i for i in range(8))))
"""
1 bytes = 8 bits which has 255 possible values.
2 bytes = 16 bits which has 65535 possible values.
4 bytes = 32 bits which has 4294967295 possible values.
8 bytes = 64 bits which has 18446744073709551615 possible values.
16 bytes = 128 bits which has 340282366920938463463374607431768211455 possible values.
32 bytes = 256 bits which has 115792089237316195423570985008687907853269984665640564039457584007913129639935 possible values.
64 bytes = 512 bits which has 13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084095 possible values.
128 bytes = 1024 bits which has 179769313486231590772930519078902473361797697894230657273430081157732675805500963132708477322407536021120113879871393357658789768814416622492847430639474124377767893424865485276302219601246094119453082952085005768838150682342462881473913110540827237163350510684586298239947245938479716304835356329624224137215 possible values.
"""
Koden fungerar visserligen, men den är en mardröm att förstå: den är ihoptryckt och svår att läsa.
Låt oss se hur samma kod skulle se ut om vi skrev den glest:
# Sparse example
bytes_and_bits = {j: j*8 for j in (1 << i for i in range(8))}
for bytes, bits in bytes_and_bits.items():
print(f"{bytes} bytes = {bits} which has {256**bytes-1} possible values")
"""
1 bytes = 8 which has 255 possible values
2 bytes = 16 which has 65535 possible values
4 bytes = 32 which has 4294967295 possible values
8 bytes = 64 which has 18446744073709551615 possible values
16 bytes = 128 which has 340282366920938463463374607431768211455 possible values
32 bytes = 256 which has 115792089237316195423570985008687907853269984665640564039457584007913129639935 possible values
64 bytes = 512 which has 13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084095 possible values
128 bytes = 1024 which has 179769313486231590772930519078902473361797697894230657273430081157732675805500963132708477322407536021120113879871393357658789768814416622492847430639474124377767893424865485276302219601246094119453082952085005768838150682342462881473913110540827237163350510684586298239947245938479716304835356329624224137215 possible values
"""
Koden ovan är mycket lättare att läsa och gör exakt samma sak som enradaren.
#7 Läsbarhet räknas
Om du inte redan har gissat det: läsbarhet räknas i Python. Ditt jobb är att skriva koden en gång. Men det är stor chans att den kommer att läsas många gånger. Med det i åtanke är det ingen bra idé att slopa vokaler i variabel- och funktionsnamn: i en situation där du kan namnge en funktion create_lst eller create_list, välj det senare.
#8 Specialfall är inte tillräckligt speciella för att bryta mot reglerna
Python [och programmering i allmänhet] är fullt av bästa praxis att följa. Det är bättre att följa dessa än att göra på ditt eget sätt, eftersom det ofta leder till inkonsekvent och svårläst kod.
#9 Även om praktisk nytta slår renlärighet
Lektion nio är en förlängning av lektion åtta. Ja, det är bättre att följa bästa praxis, men att anstränga sig till det yttersta för att hålla sig till reglerna kan också resultera i svårläst kod. Alltså kan varje regel ha ett undantag. Om ditt sätt att lösa ett problem är mer praktiskt, mer läsbart och lättare att förstå, är det bättre att avvika från etablerad bästa praxis.
#10 Fel ska aldrig passera tyst
Ett tyst fel är när ett program returnerar en felkod eller None i stället för att höja ett undantag. Det är bättre att ett program kraschar än att felet tystas och körningen fortsätter. I längden kan tystade fel leda till buggar i ditt program som är mycket svårare att få bort.
#11 Om de inte tystas uttryckligen
Lektion elva är en förlängning av lektion tio. Det finns tillfällen då du kan vilja ignorera fel som orsakas av ditt program. I sådana fall är bästa praxis att uttryckligen tysta felet i din kod.
#12 Stå emot frestelsen att gissa i mötet med tvetydighet
Datorer gör bara det vi säger åt dem att göra: om din kod inte beter sig som du vill, är det för att den gör vad du har sagt åt den att göra. Att försöka åtgärda beteendet genom att blint prova flera olika lösningar tills en fungerar är en dålig strategi – du kan sluta med att maskera problemet i stället för att lösa det. Motstå frestelsen. Tänk i stället igenom logiken i problemet och använd kritiskt tänkande för att ta fram en lämplig lösning.
#13 Det bör finnas ett – och helst bara ett – uppenbart sätt att göra det
Programmeringsspråket Perls motto är: ”Det finns mer än ett sätt att göra det!” För många alternativ leder ofta till beslutsångest. En liknande situation uppstår när det finns flera sätt att skriva kod som uppnår samma mål. Du får mer flexibilitet i hur du skriver kod, men nu måste du lära dig alla möjliga sätt koden kan vara skriven för att kunna läsa den: det extra arbete som krävs för att lära sig alla scenarier är onödigt.
#14 Även om det sättet kanske inte är uppenbart från början – om du inte är holländare
Den här aforismen visar Tim Peters humor: Guido van Rossum, skaparen av programmeringsspråket Python och Pythons Benevolent Dictator For Life (BDFL), är holländare. Det är ett skämt som påminner oss om att förmågan att förstå och minnas Pythons språkliga regler är svårt för alla utom dess skapare.
#15 Nu är bättre än aldrig
Den här aforismen säger oss att kod som fastnar i en oändlig loop eller hänger sig är sämre än kod som inte gör det.
#16 Även om aldrig ofta är bättre än just nu
Fortsättning på lektion sexton: det är bättre att vänta på att ditt program ska köra klart än att avbryta det i förtid och få felaktiga resultat.
#17 Om implementationen är svår att förklara är det en dålig idé
Det räcker inte att du själv förstår dina implementationer – ”jag vet vad jag försöker säga” håller inte. Programmering är en lagsport, och om du inte kan förklara din implementation för dina kollegor är det mycket troligt att du har gjort lösningen för komplicerad.
#18 Om implementationen är lätt att förklara kan det vara en bra idé
Men att koden är lätt att förklara betyder inte nödvändigtvis att den inte är dålig – det betyder bara att den är lätt att förklara. Du kan fortfarande ha dålig kod, men det faktum att den är lätt att förklara betyder att du är på rätt väg.
#19 Namnrymder är en hejdundrande bra idé – låt oss göra fler sådana!
En namnrymd är en abstraktion som används i Python för att organisera namn som tilldelas objekt i ett program. När den ställs inför en viss namnrymd och räckvidd kan Python avgöra vilket objekt du hänvisar till när du anropar ett symboliskt namn. Allt denna aforism säger är att sättet Python organiserar de symboliska namnen under huven är riktigt imponerande.
Slutsats
I den här artikeln har vi presenterat vår tolkning av Zen of Python, riktlinjer skapade för att uppmuntra Pythonprogrammerare att skriva ren, läsbar kod. Medan vissa ser Zen of Python som den ultimata planen för sömlöst kodskrivande, tar andra den mindre seriöst. Vi föreslår att du provar att tillämpa principerna på din egen kod för att se hur de kan förbättra ditt arbete på nära håll. Om du vill lära dig mer om att skriva optimerad kod kan du ta en titt på DataCamps Writing Efficient Python Code.