Python na poważnie - ebook
Python na poważnie - ebook
Rozwijaj swoje umiejętności programowania w Pythonie, zagłębiając się w tajniki języka przy pomocy książki Python na poważnie. Napisana z myślą o developerach i doświadczonych programistach książka Python na poważnie bazuje na ponad 15-letnim doświadczeniu w pracy z Pythonem, uczy czytelników, jak unikać typowych błędów, jak pisać kod w bardziej produktywny sposób i jak szybciej budować lepsze programy. Omówimy szereg zaawansowanych zagadnień, takich jak wielowątkowość i memoizacja, przedstawimy porady ekspertów m.in. w zakresie projektowania interfejsów API i obsługi baz danych, a także wytłumaczymy pewne wewnętrzne mechanizmy, aby pomóc w lepszym zrozumieniu języka Python. Na początku dowiesz się, jak rozpocząć projekt i rozwiązać takie kwestie jak numerowanie wersji i automatyczne sprawdzanie kodu. Później zobaczysz, jak efektywnie definiować funkcje, wybierać odpowiednie struktury danych i biblioteki, budować przyszłościowe programy, przygotowywać oprogramowanie do dystrybucji oraz optymalizować swoje programy, także na poziomie kodu bajtowego. Ponadto dowiesz się jak: Tworzyć i wykorzystywać efektywne dekoratory i metody, z uwzględnieniem metod abstrakcyjnych, statycznych i klas Używać Pythona do programowania funkcyjnego przy pomocy generatorów oraz funkcji czystych i funkcyjnych Rozszerzać narzędzie flake8 o analizę drzewa składniowego AST, wprowadzając bardziej zaawansowaną technikę automatycznego sprawdzania kodu Przeprowadzać dynamiczną analizę wydajności w celu wykrywania słabych punktów w kodzie Korzystać z relacyjnych baz danych, a także efektywnie zarządzać danymi i przesyłać je strumieniowo przy użyciu PostgreSQL Wznieś swoje umiejętności na wyższy poziom. Ucz się od ekspertów i zostań poważnym programistą Pythona dzięki książce Python na poważnie!
Kategoria: | Programowanie |
Zabezpieczenie: |
Watermark
|
ISBN: | 978-83-01-20641-3 |
Rozmiar pliku: | 1,6 MB |
FRAGMENT KSIĄŻKI
Napisanie tej pierwszej książki wymagało ogromnego wysiłku. Z perspektywy czasu widzę, że nie miałem pojęcia, jak zwariowana będzie ta podróż i jak dużo przyniesie mi satysfakcji.
Jak to mówią, gdy chcesz iść szybko, idź sam, ale jeśli chcesz dojść daleko, to weź kogoś ze sobą. To czwarta edycja mojej książki i jej powstanie nie byłoby możliwe bez pomocy innych. Jest to wynik pracy zespołowej i chciałbym podziękować wszystkim, którzy wzięli w niej udział.
Większość osób bez namysłu zgodziła się udzielić mi wywiadu, obdarzając mnie zaufaniem oraz poświęciła swój czas, znacząco podnosząc wartość edukacyjną tej książki. Dziękuję Dougowi Hellmannowi za doskonałe porady dotyczące budowania bibliotek, Joshua Harlowowi za poczucie humoru i wiedzę o rozproszonych systemach, Christophowi de Vienne za doświadczenie w projektowaniu platform programistycznych, Victorowi Stinnerowi za niesamowitą wiedzę o CPythonie, Dimitrowi Fontaine za mądrość w dziedzinie baz danych, Robertowi Collinsowi za eksperymentowanie na testach, Nickowi Coghlanowi za pracę nad poprawą kondycji języka Python oraz Paulowi Tagliamonte za wspaniały hakerski zapał.
Dziękuję zespołowi No Starch za wspólną pracę nad wyniesieniem tej książki na całkiem nowy poziom, w szczególności dla Liz Chadwick za umiejętności redaktorskie, Laurel Chun za utrzymywanie mnie na właściwej drodze i Mikowi Driscollowi za wgląd techniczny.
Jestem wdzięczny społecznościom rozwijającym darmowe oprogramowanie, które dzieląc się swoją wiedzą, pomogły mi w rozwoju – w szczególności społeczności Pythona, która zawsze była otwarta i entuzjastyczna.Wprowadzenie
Skoro sięgnąłeś po tę książkę, prawdopo dobnie już od jakiegoś czasu programujesz w języku Python. Być może poznałeś go, korzystając z samouczków, dociekliwe analizując istniejące programy lub rozpocząłeś naukę od podstaw. Tak czy owak, opracowałeś swój sposób nauki. Ja poznawałem Pythona w taki sam sposób, dopóki 10 lat temu nie zacząłem pracy nad dużym projektem open source.
Po napisaniu pierwszego programu można łatwo odnieść wrażenie, że zrozumiało się Pythona. Język jest prosty w użyciu. Ale jego opanowanie i pełne zrozumienie zalet i wad wymagają lat praktyki.
Gdy zacząłem programowanie w Pythonie, budowałem swoje pierwsze biblioteki i aplikacje na skalę „domowych projektów”. Sytuacja zmieniła się, odkąd zacząłem wraz z setkami programistów pracować nad oprogramowaniem, z którego korzystają tysiące użytkowników. Na przykład platforma OpenStack – projekt, w którym współuczestniczę – składa się z 9 milionów wierszy kodu Pythona, który musi być zwięzły, efektywny i skalowalny, aby dostosowywać chmurę obliczeniową do potrzeb jej użytkowników. W projekcie o tak dużym rozmiarze, takie zadania jak testowanie czy dokumentowanie zdecydowanie wymagają automatyzacji, w przeciwnym przypadku nie zostaną w ogóle zrealizowane.
Zanim zacząłem pracę na projektami na tak niewyobrażalnie dużą skalę, wydawało mi się, że całkiem dobrze znam już język Python, jednak wiele się jeszcze nauczyłem. Te projekty dały mi również możliwość współpracowania z wiodącymi ekspertami w dziedzinie Pythona i uczenia się od nich. Nauczyłem się od nich wszystkiego, od ogólnych zasad dotyczących architektury i projektowania, po różne pomocne wskazówki i sztuczki. W tej książce podzielę się najważniejszymi zdobytymi informacjami, aby pomóc czytelnikom nie tylko w tworzeniu lepszych programów Pythona, lecz także robieniu tego bardziej efektywnie.
Pierwsza wersja tej książki, zatytułowana The Hacker’s Guide to Python, została opublikowana w 2014 roku. Python na poważnie to czwarta edycja, z uaktualnioną oraz całkiem nową zawartością. Życzymy przyjemnej lektury.
Kto i dlaczego powinien przeczytać tę książkę
Ta książka została napisana z myślą o koderach i producentach oprogramowania, którzy chcą jeszcze lepiej poznać język Python.
Przedstawia ona metody i porady, które pomagają w maksymalnym wykorzystaniu możliwości języka Python i projektowaniu przyszłościowych programów. Jeśli pracujesz już nad projektem, to będziesz mieć możliwość od razu zastosować omawiane techniki do udoskonalenia swojego aktualnego kodu. Jeśli rozpoczynasz swój pierwszy projekt, to będziesz mógł utworzyć go zgodnie z najlepszymi praktykami.
Omówimy pewne wewnętrzne elementy języka Python, pomocne w rozwijaniu umiejętności pisania efektywnego kodu. Poznasz wewnętrzne mechanizmy języka, co pomoże Ci w zrozumieniu problemów i nieefektywności.
Książna oferuje również praktyczne, dobrze sprawdzone rozwiązania takich problemów jak testowanie, przenoszenie i skalowanie kodu, aplikacji oraz bibliotek Pythona. Dzięki temu można uczyć się na błędach innych programistów i odkryć strategie, które wspierają długoterminowe utrzymywanie kodu.
O tej książce
Niniejsza książka została zaprojektowana w taki sposób, aby nie trzeba było czytać jej od początku do końca. Możesz przejść od razu do części, które uważasz za najbardziej interesujące lub przydatne w pracy. Książka przedstawia szeroki zakres porad i praktycznych wskazówek. Oto szybki przegląd zawartości poszczególnych rozdziałów.
Rozdział 1 dostarcza wskazówek dotyczących aspektów, które warto wziąć pod uwagę przed rozpoczęciem projektu, takich jak struktura projektu, numerowanie wersji, konfigurowanie automatycznego sprawdzania błędów. Na końcu znajduje się wywiad z Joshuą Harlowem.
Rozdział 2 zawiera wprowadzenie do modułów, bibliotek i platform Pythona oraz zdradza pewne tajniki ich działania. Przedstawia porady dotyczące stosowania modułu sys, czerpania większych korzyści z menedżera pakietów pip, wybierania platformy najlepiej dostosowanej do potrzeb i stosowania bibliotek standardowych oraz zewnętrznych. Rozdział ten zawiera również wywiad z Dougiem Hellmannem.
Rozdział 3 udziela porad dotyczących dokumentowania projektów i zarządzania interfejsami API w miarę jak projekty ewoluują po opublikowaniu. Przedstawione zostaną konkretne zalecenia dotyczące stosowania narzędzia Sphinx do automatyzowania pewnych zadań związanych z dokumentowaniem. W tym rozdziale znaleźć można wywiad z Christophem de Vienne.
Rozdział 4 omawia odwieczny problem stref czasowych i najlepszego obsługiwania ich w programach przy użyciu obiektów datetime oraz tzinfo.
Rozdział 5 pomaga w dostarczaniu oprogramowania użytkownikom, przedstawiając wskazówki dotyczące dystrybucji. Omówione zostaną standardy zarządzania pakietami i ich dystrybucją, biblioteki distutils oraz setuptools, a także łatwe sposoby odkrywania dynamicznych funkcji w pakiecie przy użyciu punktów wejścia. Wywiadu udzielił Nick Coghlan.
Rozdział 6 zawiera porady dotyczące testów jednostkowych (unit tests) z opisem najlepszych praktyk oraz konkretnymi instrukcjami automatyzowania testów jednostkowych przy użyciu pytest. Omówione zostaną również środowiska wirtualne służące do zwiększania izolacji testów. Wywiadu udzielił Robert Collins.
Rozdział 7 zawiera szczegółowe omówienie metod i dekoratorów, ilustrując możliwości zastosowania Pythona do programowania funkcyjnego. W tym rozdziale przedstawimy porady, jak i kiedy używać dekoratorów oraz jak tworzyć dekoratory dla dekoratorów. Przyjrzymy się również metodom statycznym, klasy oraz abstrakcyjnym i pokażemy, jak łączyć wszystkie trzy w celu uzyskania solidniejszego programu.
Rozdział 8 przedstawia pewne techniki programowania funkcyjnego, które można zaimplementować w Pythonie. W tym rozdziale omówione zostaną generatory, wyrażenia listowe, funkcje funkcyjne i typowe narzędzia do ich implementowania, jak również przydatna biblioteka functools.
Rozdział 9 zagląda w głąb języka i omawia drzewo składniowe AST, które stanowi wewnętrzną strukturę Pythona. Zajmuje się również rozszerzaniem flake8 o analizę drzewa AST, co umożliwia sprawdzanie programów w bardziej zaawansowany sposób. Na zakończenie rozdziału przedstawiony zostanie wywiad z Paulem Tagliamonte.
Rozdział 10 oferuje wskazówki dotyczące optymalizowania wydajności przez zastosowanie odpowiednich struktur danych, efektywne definiowanie funkcji oraz przeprowadzanie dynamicznej analizy wydajności w celu zidentyfikowania wąskich gardeł w kodzie. Poruszymy również problem memoizacji oraz redukowania ilości niepotrzebnie kopiowanych danych. Rozdział zawiera wywiad z Victorem Stinnerem.
Rozdział 11 zajmuje się trudnym tematem wielowątkowości, odpowiadając m.in. na pytania: jak i kiedy lepiej jest użyć wielu wątków zamiast wielu procesów oraz czy do tworzenia skalowalnych programów używać architektury zorientowanej na zdarzenia, czy na usługi.
Rozdział 12 zajmuje się relacyjnymi bazami danych. Przyjrzymy się, jak one działają i jak użyć PostgreSQL do efektywnego zarządzania danymi i przesyłania ich strumieniowo. Wywiadu udzielił Dimitri Fontaine.
Na zakończenie, rozdział 13 oferuje solidne porady dotyczące różnych zagadnień, takich jak: zapewnianie zgodności kodu z wersjami Python 2 i 3, tworzenie funkcyjnego kodu przypominającego Lisp, stosowanie menedżerów kontekstu oraz redukowanie liczby powtórzeń za pomocą biblioteki attr.1
Rozpoczynanie projektu
W pierwszym rozdziale omówimy wybrane aspekty rozpoczynania projektu i pokażemy, co warto wcześniej przemyśleć, np. jakiej wersji Pythona użyć, jaką strukturę modeli zastosować, jak efektywnie numerować wersje oprogramowania i jak zastosować najlepsze praktyki programowania w automatycznym wykrywaniu błędów.
Wersje Pythona
Przed rozpoczęciem projektu trzeba zadecydować, która wersja bądź które wersje Pythona będą w nim wspierane. Decyzja ta nie jest wbrew pozorom taka prosta.
Powszechnie wiadomo, że Python obsługuje jednocześnie wiele wersji. Każda podrzędna wersja interpretera otrzymuje 18-miesięczne wsparcie w zakresie naprawiania błędów i 5-letnie wsparcie w zakresie bezpieczeństwa. Na przykład wersja Python 3.7 opublikowana 27 czerwca 2018 roku będzie obsługiwana do czasu opublikowania wersji Python 3.8, co powinno nastąpić koło października 2019 roku. W okolicach grudnia 2019 roku pojawi się ostatnie poprawiające błędy wydanie wersji Python 3.7 i wszyscy powinni dokonać przeniesienia na wersję Python 3.8. Każda nowa wersja Pythona wprowadza nowe funkcje i oznacza pewne starsze funkcje jako przestarzałe (deprecated). Rysunek 1.1 przedstawia linię czasową.
Rysunek 1.1. Linia czasowa publikacji Pythona
Ponadto powinniśmy wziąć pod uwagę problem wersji Python 2 kontra Python 3. Osoby korzystające z (bardzo) starych platform mogą nadal potrzebować obsługi dla wersji Python 2, ponieważ wersja Python 3 nie została udostępniona na tych platformach, ale zasadniczo należy – jeśli to możliwe – zapomnieć o wersji Python 2.
Oto szybki sposób określania, która wersja będzie potrzebna:
• Wersja 2.6 i starsze są oznaczone jako przestarzałe, dlatego nie zalecamy zawracania sobie głowy ich obsługą. Jeśli z jakiegoś powodu zamierzasz obsługiwać w programie te starsze wersje, to miej świadomość, że będziesz mieć trudności z zapewnieniem jednocześnie wsparcia dla wersji Python 3.x. Niestety w starszych systemach możesz nadal napotkać wersję Python 2.6 – wyrazy współczucia, jeśli tak się zdarzy!
• Wersja 2.7 jest i pozostanie ostatnią wersją Python 2.x. Obecnie praktycznie każdy system obsługuje lub może w jakiś sposób obslugiwać wersję Python 3, więc o ile nie zajmujesz się archeologią, nie musisz zaprzątać sobie głowy wersją Python 2.7. Wersja ta przestanie być wspierana po 2020 roku, dlatego zdecydowanie nie warto opierać na niej nowo tworzonym oprogramowania.
• W momencie pisania tej książki wersja 3.7 stanowi najnowszą wersję Python 3 i powinna być preferowaną opcją. Jednak jeśli Twój system operacyjny jest dystrybuowany z wersją 3.6 (większość systemów operacyjnych, z wyjątkiem Windows, zawiera wersję 3.6 lub późniejszą), to upewnij się, że Twoja aplikacja będzie działać również przy użyciu wersji 3.6.
Techniki pisania programów, które obsługują zarówno wersję Python 2.7, jak i 3.x, są omówione w rozdziale 13.
Na zakończenie chcielibyśmy zaznaczyć, że książka ta została napisana z myślą o wersji Python 3.
Układ projektu
Rozpoczynanie nowego projektu zawsze wiąże się z odrobiną niepewności. Nie wiemy jeszcze, jaką strukturę będzie miał nasz projekt, dlatego możemy mieć wątpliwości, jak zorganizować jego pliki. Jednak właściwe zrozumienie najlepszych praktyk pomaga w planowaniu początkowej struktury. Oto kilka wskazówek, jak należy i jak nie należy planować układu projektu.
Co robić
Przede wszystkim przemyśl strukturę projektu, która powinna być dość prosta. Z rozwagą używaj pakietów i hierarchii: nawigowanie po wielopoziomowej hierarchii może być koszmarem, a płaska hierarchia ma tendencje do nadmiernego rozrastania się.
Unikaj często popełnianego błędu polegającego na przechowywaniu testów jednostkowych poza katalogiem pakietu. Te testy zdecydowanie powinny zostać umieszczone w podpakiecie oprogramowania, aby nie zostały przypadkiem automatycznie zainstalowane jako główny moduł tests przez setuptools (lub inną bibliotekę do zarządzania pakietami). Dzięki umieszczeniu w podpakiecie mogą one być instalowane i w przyszłości wykorzystywane przez inne pakiety, umożliwiając użytkownikom projektowanie własnych testów jednostkowych.
Rysunek 1.2 ilustruje, jak powinna wyglądać standardowa hierarchia plików.
Standardowa nazwa skryptu instalacyjnego Pythona to setup.py. Towarzyszy mu plik setup.cfg, który powinien zawierać szczegóły konfiguracji skryptu instalacyjnego. Po uruchomieniu plik setup.py zainstaluje nasz pakiet przy użyciu narzędzi do dystrybucji Pythona.
Możemy również przekazać użytkownikom najważniejsze informacje, umieszczając je w pliku o nazwie README.rst (lub README.txt albo dowolnej innej nazwie). Ponadto katalog docs powinien zawierać dokumentację pakietu w formacie reStructuredText, który zostanie wykorzystany przez narzędzie Sphinx (patrz rozdział 3).
Pakiety będą często musiały zawierać dodatkowe dane do wykorzystania w oprogramowaniu, takie jak obrazy, skrypty powłoki itp. Niestety nie ma powszechnie uznanego standardu, który określałby miejsce przechowywania tych plików, dlatego umieszczamy je w tym miejscu, które ma największy sens z perspektywy ich funkcji w projekcie. Na przykład szablony aplikacji WWW można umieszczać w katalogu templates, w katalogu głównym pakietu.
Rysunek 1.2. Standardowy katalog pakietu
Oto inne często stosowane katalogi najwyższego poziomu:
• etc z przykładowymi plikami konfiguracji,
• tools ze skryptami powłoki lub powiązanymi narzędziami,
• bin z napisanymi przez nas skryptami binarnymi, które zostaną zainstalowane przez setup.py.
Czego nie robić
Istnieje pewien błąd projektowy, jaki często spotykam w strukturach projektów, które nie zostały do końca przemyślane: niektórzy programiści tworzą pliki i moduły, opierając się na typie kodu, jaki będzie się w nich znajdował. Na przykład tworzą pliki funkcje.py lub wyjątki.py. Jest to fatalne podejście i nie ułatwia innym programistom nawigowania po kodzie. Czytając kod, programista oczekuje, że obszar funkcjonalny programu będzie zawarty w jednym pliku. Podejście, które bez powodu zmusza czytających do przeskakiwania między plikami, nie sprzyja organizacji kodu.
Kod należy organizować na podstawie funkcji, a nie typów.
Kolejnym złym pomysłem jest tworzenie katalogu modułu, który zawiera jedynie plik __init__.py, ponieważ reprezentuje on niepotrzebne zagnieżdżanie. Na przykład nie należy tworzyć katalogu o nazwie hooks z jednym plikiem o nazwie hooks/__init__.py, gdy wystarczy plik hooks.py. Jeśli tworzymy katalog, to powinien on zawierać kilka innych plików Pythona, które należą do kategorii reprezentowanej przez katalog. Niepotrzebne budowanie głębokiej hierarchii jest mylące.
Ponadto należy zachować szczególną ostrożność, umieszczając kod w pliku __init__.py. Ten plik zostanie wywołany i wykonany przy pierwszym załadowaniu danego modułu. Umieszczenie niewłaściwego kodu w pliku __init__.py może pociągać z sobą niepożądane skutki uboczne. W rzeczywistości pliki __init__.py lepiej z reguły pozostawić puste, chyba że wiemy, co robimy. Jednak nie należy całkowicie usuwać plików __init__.py, gdyż w przeciwnym wypadku nie będzie można w ogólne zaimportować modułu Pythona: w języku Python katalog musi zawierać plik __init__.py, aby mógł być traktowany jak podmoduł.
Numerowanie wersji
Wersje oprogramowania muszą zostać oznaczone tak, aby użytkownicy wiedzieli, która wersja jest najnowsza. W każdym projekcie użytkownicy muszą mieć możliwość opracowania linii czasowej dla ewoluującego kodu.
Istnieje nieskończona liczba sposobów organizowania numerów wersji. Jednak specyfikacja PEP 440 wprowadza format wersji, który należy stosować w każdym pakiecie Pythona, a najlepiej w każdej aplikacji, aby inne programy i pakiety mogły łatwo i trafnie określać, która wersja pakietu jest potrzebna.
PEP 440 definiuje następującą postać wyrażenia regularnego do numerowania wersji:
N+
To wyrażenie obsługuje standardowe numerowanie, takie jak 1.2 czy 1.2.3. Warto zwrócić uwagę na kilka szczegółów:
• Wersja 1.2 to odpowiednik 1.2.0, a 1.3.4 to odpowiednik 1.3.4.0, itd.
• Wersje pasujące do wyrażenia N+ stanowią wydania ostateczne.
• Wersje oparte na dacie, takie jak 2013.06.22, są uznawane za nieprawidłowe. Automatyczne narzędzia, zaprojektowane z myślą o wykrywaniu numerów wersji w formacie PEP 440, zgłoszą (bądź powinny zgłosić) błąd, jeśli wykryją numer wersji większy lub równy 1980.
• Ostatni składnik może również mieć następujący format:
– N+aN (np. 1.2a1) oznacza wydanie alfa, czyli wersję, która może nie być stabilna lub może nie zawierać pewnych funkcji.
– N+bN (np. 2.3.1b2) oznacza wydanie beta, czyli wersję, która może oferować wszystkie funkcje, ale również zawierać pewne błędy.
– N+cN lub N+rcN (np. 0.4rc1) oznacza kandydata do wydania, czyli wersję, która może zostać wydana jako produkt ostateczny, o ile nie ujawnią się jakieś istotne problemy. Przedrostki rc oraz c mają to samo znaczenie, ale jeśli występują obok siebie, wydania rc uznawane są za nowsze niż wydania c.
• Można użyć również następujących przyrostków:
– Przyrostek .postN (np. 1.4.post2) jest używany w wersjach następujących po wydaniu oprogramowania, które służą zazwyczaj do poprawiania drugorzędnych błędów powstałych w procesie publikacji, takich jak pomyłki w dokumentacji wydania. Wydając wersję z poprawkami programu, zamiast stosować przyrostek .postN, należy zwiększyć pomocniczy składnik numeru wersji.
– Przyrostek .devN (np. 2.3.4.dev3) oznacza wydanie deweloperskie. Identyfikuje wydanie poprzedzające określoną wersję, np. 2.3.4.dev3, i oznacza trzecią deweloperską wersję wydania 2.3.4, przed jakimkolwiek wydaniem alfa, beta, kandydującym lub ostatecznym. Odradza się stosowanie tego przyrostka, ponieważ jest on mniej zrozumiały
dla ludzi.
Ten schemat powinien okazać się wystarczający w większości przypadków.
Być może słyszałeś o specyfikacji Semantic Versioning, która przedstawia osobne wytyczne dotyczące numerowania wersji. Ta specyfikacja częściowo pokrywa się ze specyfikacją PEP 440, ale niestety nie jest z nią w pełni zgodna. Na przykład specyfikacja Semantic Versioning zaleca numerowanie wydań poprzedzających ostateczne przy użyciu schematu 1.0.0-alpha+001, który nie jest zgodny ze specyfikacją PEP 440.
Wiele rozproszonych systemów kontroli wersji (Distributed Version Control System – DVCS), takich jak Git czy Mercurial, umożliwia generowanie numerów wersji przy użyciu identyfikującego skrótu (patrz git describe dla programu Git). Niestety ten system nie jest zgodny ze schematem zdefiniowanym w specyfikacji PEP 440, między innymi dlatego, że identyfikujących skrótów nie można sortować.
Style programowania i automatyczne sprawdzanie
Style programowania stanowią delikatny temat, jednak warto go poruszyć przed zagłębieniem się w szczegóły języka Python. W odróżnieniu od wielu innych języków programowania, do definiowania bloków w Pythonie używa się wcięć. Choć takie rozwiązanie dostarcza prostą odpowiedź na odwieczne pytanie „Gdzie umieścić nawiasy klamrowe?”, pociąga za sobą nowe pytanie: „W jaki sposób stosować wcięcia?”
Było to jedno z pierwszych pytań zadanych przez społeczność programistów, dlatego twórcy Pythona, bardzo roztropnie, opublikowali specyfikację PEP 8: Style Guide for Python Code (https://www.python.org/dev/peps/pep-0008/).
Ten dokument definiuje standardowy styl pisania kodu Pythona. Lista zaleceń sprowadza się do następujących:
• Należy używać czterech spacji dla każdego poziomu wcięcia.
• Wiersze powinny zawierać maksymalnie 79 znaków.
• Definicje funkcji najwyższego poziomu i definicje klas należy rozdzielać dwoma pustymi wierszami.
• W plikach powinno się stosować kodowanie ASCII lub UTF-8.
• Każdy moduł należy importować w osobnej instrukcji import i osobnym wierszu. Instrukcje importowania należy umieszczać na początku pliku, po komentarzach i ciągach dokumentacyjnych, grupując je na standardowe, następnie zewnętrzne, a na zakończenie lokalne biblioteki.
• Nie należy umieszczać niepotrzebnych spacji w nawiasach okrągłych, kwadratowych bądź klamrowych ani przed przecinkami.
• Wyrazy w nazwach klas powinny rozpoczynać się wielką literą (np. CamelCase), wyjątki powinny zawierać przyrostek Error (jeśli są błędami), a nazwy funkcji powinny składać się z wyrazów rozpoczynających się małą literą oraz podkreśleń (np. wyrazy_oddzielone_podkresleniami). Natomiast _prywatne atrybuty oraz metody powinny rozpoczynać się od podkreślenia.
Te zalecenia nie są trudne w implementacji i mają sens. Większość programistów Pythona nie ma problemów z ich przestrzeganiem podczas pisania kodu.
Jednak błądzić jest rzeczą ludzką, a analizowanie kodu pod kątem przestrzegania zaleceń specyfikacji PEP 8 nie należy do przyjemności. Na szczęście istnieje narzędzie pep8 (dostępne na stronie: https://pypi.org/project/pep8/), które może automatycznie sprawdzić dowolny plik Pythona, jaki do niego prześlemy. Wystarczy zainstalować narzędzie pep8 przy użyciu pip, aby móc stosować je na dowolnym pliku w następujący sposób:
$ pep8 hello.py
hello.py:4:1: E302 expected 2 blank lines, found 1
$ echo $?
1
W tym przykładzie użyliśmy pep8 na przykładowym pliku hello.py. Wynik wskazuje, które wiersze i kolumny nie są zgodne ze specyfikacją PEP 8 i zgłasza każdy problem z kodem – w tym wypadku w wierszu 4 i kolumnie 1. Naruszenia reguł MUST w specyfikacji są zgłaszane jako błędy, których kod błędu rozpoczyna się od E. Natomiast drugorzędne problemy są zgłaszane jako ostrzeżenia, których kod błędu rozpoczyna się od W. Trzycyfrowy kod, następujący po pierwszej literze, precyzuje typ błędu lub ostrzeżenia.
Cyfra setek wskazuje ogólną kategorię kodu błędu np. błędy rozpoczynające się od E2 sygnalizują problemy ze spacjami, błędy rozpoczynające się od E3 sygnalizują problemy z pustymi wierszami, a ostrzeżenia rozpoczynające się od W6 sygnalizują użycie funkcji oznaczonej jako przestarzała. Listę wszystkich kodów znaleźć można w dokumentacji readthedocs narzędzia pep8 (https://pep8.readthedocs.io/).