PEP 8 to oficjalny przewodnik stylu dla kodu w Pythonie, napisany przez Guido van Rossuma, Barry'ego Warsawa i Alyssę Coghlan w 2001 roku. Określa m.in. 4 spacje wcięcia, limit 79 znaków w linii i nazewnictwo (snake_casedla funkcji i zmiennych,CapWordsdla klas). PEP 8 nie ma numerowanych wersji, bo jest żywym dokumentem zmienianym przez kolejne poprawki, a co roku w październiku wychodzi nowa wersja samego Pythona.
Kod czytasz znacznie częściej, niż go piszesz: wracasz do własnych funkcji po tygodniu, a w zespole czytasz cudze. Dlatego programiści Pythona uzgodnili wspólne reguły zapisu. Są zebrane w dokumencie o nazwie PEP 8. W tym artykule wyjaśniamy, czym jest, jakie ma najważniejsze zasady, jak sprawdzić kod narzędziami, a także jak naprawdę zmienia się ten dokument i jak ma się do corocznych wydań Pythona. Wszystkie przykłady kodu i wyniki narzędzi zostały uruchomione w Pythonie 3.13 z aktualnymi wersjami narzędzi.
Czym jest PEP 8?
PEP to skrót od Python Enhancement Proposal, czyli dokumentu, w którym opisuje się propozycje zmian i zasady dotyczące Pythona. Numer 8 nosi przewodnik stylu kodu, który stworzyli Guido van Rossum (twórca Pythona), Barry Warsaw i Alyssa Coghlan. Dokument powstał 5 lipca 2001 roku na bazie wcześniejszego eseju Guido o stylu kodu i opisuje konwencje dla biblioteki standardowej Pythona.
Najważniejsze zdanie z samego dokumentu to: kod czyta się znacznie częściej, niż się go pisze. Cała reszta wynika z tej zasady. PEP 8 ma oficjalny status Active i typ Process, o czym więcej piszemy niżej.
Po co stosować PEP 8?
Powodów jest kilka:
- Czytelność: kod wygląda jednakowo w każdym projekcie, więc szybciej go rozumiesz.
- Mniej sporów w zespole: o wcięciach i nazwach decyduje dokument, a nie czyjeś upodobanie.
- Łatwiejsze przeglądy kodu: różnice dotyczą logiki, a nie formatowania.
- Mniej błędów: część reguł (np. porównania z
None, gołeexcept) chroni przed realnymi pomyłkami.
Sam PEP 8 uczy jednak zdrowego rozsądku. Ostrzega przed głupią konsekwencją i wymienia cztery sytuacje, gdy zasadę można zignorować: gdy kod stałby się mniej czytelny, gdy otoczenie już ją łamie, gdy kod powstał, zanim zasada się pojawiła, albo gdy kod musi zachować zgodność ze starszymi wersjami Pythona. Dodaje też, żeby nie łamać zgodności wstecznej tylko po to, by zadowolić PEP 8. Najważniejsza jest spójność w obrębie projektu, a jeśli zespół ma własny przewodnik, to jego reguły są ważniejsze.
Jakie są najważniejsze zasady PEP 8?
Poniższa tabela zbiera reguły, z którymi spotkasz się najczęściej. Wartości pochodzą z aktualnej wersji dokumentu.
| Obszar | Zasada |
|---|---|
| Wcięcia | 4 spacje na poziom (tabulatory tylko w istniejącym kodzie, który już ich używa) |
| Długość linii | 79 znaków; docstringi i komentarze do 72; zespoły mogą uzgodnić do 99 |
| Puste linie | 2 przed funkcjami i klasami najwyższego poziomu, 1 między metodami klasy |
| Importy | jeden na linię, na górze pliku; grupy: biblioteka standardowa, zewnętrzne, lokalne, rozdzielone pustą linią |
| Spacje | po przecinku tak; wokół = w argumentach nazwanych nie; wokół operatorów (=, +, ==) jedna |
Porównania z None | zawsze przez is albo is not, nigdy == |
| Wartości logiczne | if lista: zamiast if lista == True: |
| Wyjątki | zamiast gołego except: użyj konkretnego typu wyjątku |
| Komentarze | aktualne; komentarz w linii poprzedzony co najmniej dwiema spacjami przed # |
Różnicę najlepiej zobaczyć na kodzie. Poniżej fragment, który łamie wiele reguł naraz:
import os,sys
def Calculate_Price(price,discount = 10):
if discount == None:
discount=0
return price-price*discount/100
class cart:
def add(self,item):
try:
self.items.append(item)
except:
pass
l = [1,2,3]
if l == True:
print("a long message that is definitely longer than seventy-nine characters in total")
A tak ten sam kod wygląda zgodnie z PEP 8:
import os
import sys
def calculate_price(price, discount=10):
if discount is None:
discount = 0
return price - price * discount / 100
class Cart:
def __init__(self):
self.items = []
def add(self, item):
try:
self.items.append(item)
except AttributeError:
raise
numbers = [1, 2, 3]
if numbers:
print(os.getcwd(), sys.version_info.major)
Pierwszy fragment sprawdzono narzędziem pycodestyle: zgłosiło 16 uwag, a drugi fragment przeszedł bez żadnej. Najczęstsze kody błędów z tej listy wyjaśnia tabela:
| Kod | Co oznacza |
|---|---|
E231 | brak spacji po przecinku |
E401 | kilka importów w jednej linii |
E302 / E305 | za mało pustych linii przed lub po definicji |
E251 | spacje wokół = w argumencie nazwanym |
E225 | brak spacji wokół operatora |
E711 / E712 | porównanie z None lub True przez == |
E722 | goły except |
E501 | linia dłuższa niż 79 znaków |
Jak nazywać zmienne, funkcje i klasy według PEP 8?
Nazewnictwo to część PEP 8, o którą pytają najczęściej. Zasady są proste:
| Element | Konwencja | Przykład |
|---|---|---|
| Funkcje i zmienne | snake_case | total_price |
| Klasy | CapWords | ShoppingCart |
| Wyjątki | CapWords, z końcówką Error dla błędów | HTTPServerError |
| Stałe | UPPER_CASE_WITH_UNDERSCORES | MAX_RETRIES |
| Elementy niepubliczne | jedno podkreślenie na początku | _items |
| Pierwszy argument metody | self (w metodach klasowych cls) | def add(self, item) |
| Konflikt ze słowem kluczowym | podkreślenie na końcu | class_ |
| Moduły | krótkie, małymi literami | shopping_cart.py |
MAX_RETRIES = 3
class HTTPServerError(Exception):
pass
class ShoppingCart:
def __init__(self):
self._items = []
def add_item(self, item_name, class_=None):
self._items.append((item_name, class_))
return len(self._items)
def total_price(prices):
return sum(prices)
cart = ShoppingCart()
print(cart.add_item("book"), total_price([1, 2, 3]), MAX_RETRIES) # 1 6 3
Dwie uwagi, które zadają początkujący. Po pierwsze, nazwa klasy z akronimem, jak HTTPServerError, jest zgodna z PEP 8, bo dokument sam podaje ją jako przykład. Po drugie, nigdy nie używaj l, O ani I jako jednoliterowych nazw, bo łatwo je pomylić z cyframi. Narzędzie ruff zgłasza l jako błąd E741. O nazwach klas i metod w kontekście programowania obiektowego piszemy w module Python OOP i w artykule o wzorcach projektowych i polimorfizmie w Pythonie.
Jak sprawdzić kod pod kątem PEP 8?
Nie musisz pamiętać wszystkich reguł. Robią to za Ciebie narzędzia, które dzielą się na dwie grupy.
| Narzędzie | Rodzaj | Co robi |
|---|---|---|
pycodestyle | linter stylu | sprawdza kod pod kątem PEP 8 (dawniej nazywał się pep8) |
flake8 | linter | łączy pycodestyle z wykrywaniem błędów, np. nieużywanych importów |
ruff | linter i formatter | szybki, ma setki reguł, w tym nazewnictwo (N) i kolejność importów (I) |
black | formatter | sam przepisuje kod w jednym, stałym stylu |
Linter zgłasza uwagi, a formatter sam poprawia kod. Nie zastępują się nawzajem, co pokazuje przykład: black uruchomiony na kodzie z błędami z poprzedniej sekcji, a następnie wynik sprawdzony przez pycodestyle.
# "zły" kod po black: poprawione białe znaki i puste linie
import os, sys
def Calculate_Price(price, discount=10):
if discount == None: # nadal błąd E711
discount = 0
return price - price * discount / 100
class cart:
def add(self, item):
try:
self.items.append(item)
except: # nadal błąd E722
pass
l = [1, 2, 3]
if l == True: # nadal błąd E712
print(
"a long message that is definitely longer than seventy-nine characters in total"
)
black naprawił spacje i puste linie, ale nie zmienił porównań z None i True, gołego except ani nazw Calculate_Price i cart. Dlatego w praktyce stosuje się oba narzędzia razem: formatter dla wyglądu, linter dla reguł.
Jest jeszcze jedna pułapka: domyślny limit linii wynosi 88 znaków w black i w ruff, a PEP 8 mówi o 79. Linia o 88 znakach przechodzi przez black, ale pycodestyle zgłosi ją jako E501 (88 > 79). Jeśli chcesz trzymać się PEP 8 literalnie, ustaw limit w pliku pyproject.toml:
;toml
[tool.black]
line-length = 79
[tool.ruff]
line-length = 79
[tool.ruff.lint]
select = ["E", "W", "F", "N", "I"]
Po takiej konfiguracji black zawija długie wywołania do 79 znaków, ale nie potrafi podzielić długiego napisu w cudzysłowie, więc taką linię trzeba skrócić ręcznie. Potwierdza to przykład powyżej. Kolejność importów zapewnia reguła I w ruff, która ustawia je w grupach: najpierw biblioteka standardowa (json, os, sys), potem biblioteki zewnętrzne, jak requests. Te narzędzia uruchamia się też w edytorze i w CI, a ich użycie w testach opisujemy w artykule o TDD i BDD w pytest oraz w module Python Testing.
Czy PEP 8 ma wersje?
Nie. To częste nieporozumienie, bo mówimy „Python 3.13” albo „ECMAScript 2025”, więc łatwo założyć, że PEP 8 też wychodzi w numerowanych wydaniach. Tymczasem:
- PEP 8 ma status Active i typ Process. Według zasad opisanych w PEP 1 taki dokument jest „nigdy nieprzeznaczony do ukończenia” i może być aktualizowany, żeby odzwierciedlać zmiany w praktyce programistycznej.
- Nie ma kolejnych edycji w rodzaju „PEP 8 v2”. Istnieje jeden dokument, którego treść zmienia się przez pojedyncze poprawki, a wcześniejsze stany można zobaczyć w historii pliku w repozytorium.
- Dokument nie jest przypisany do konkretnej wersji Pythona. Wspomina o wersjach tylko przy konkretnych regułach, np. że backslash w wielu instrukcjach
withbył potrzebny „przed Pythonem 3.10”.
Dlatego w tym artykule zamiast „historii wersji” pokazujemy historię zmian, czyli to, co faktycznie się działo z dokumentem.
Jak wyglądają prace nad zmianami w PEP 8?
Proces wynika z PEP 1, czyli dokumentu opisującego, jak działają PEP-y:
- Propozycja zmiany trafia na forum discuss.python.org (kategoria PEP) lub do repozytorium python/peps na GitHubie jako pull request.
- Redaktorzy PEP pilnują formy i numeracji, ale nie oceniają merytorycznie.
- Zmiany merytoryczne omawia społeczność rozwijająca Pythona, a ostateczną władzę w sprawie PEP-ów ma Rada Sterująca (Steering Council).
- Po przyjęciu zmiana jest zapisywana jako zwykły commit w historii pliku.
W repozytorium python/peps historia pliku PEP 8 liczy około 160 commitów od 2001 roku. Poniższa oś czasu pokazuje kilka z nich. Opisy pochodzą z komunikatów commitów, a nie z pełnej analizy zmian w tekście.
| Data | Zmiana (według opisu commitu) |
|---|---|
| 2001-07-05 | powstanie PEP 8 |
| 2002-05-24 | silna preferencja spacji zamiast tabulatorów |
| 2005-12-14 | duża aktualizacja po dyskusji na liście python-dev |
| 2007 | zalecenie, by unikać zbyt szerokich i gołych klauzul except |
| 2010-11-28 | zmiana rad dotyczących łamania linii: backslashe przestają być zalecane |
| 2013-08-02 | nowe sformułowanie o długości linii (mniejsza zachęta do 100 znaków) |
| 2014-11-30 | nowa sekcja o cudzysłowach |
| 2016-01-05 | reguły dla adnotacji funkcji dostosowane do PEP 484 |
| 2016-04-15 | łamanie wyrażeń przed operatorem binarnym (styl Knutha) |
| 2018-01-19 | zalecenia dla adnotacji zmiennych |
| 2020-06-26 | zmiana wymogu dotyczącego standardowego angielskiego |
| 2025-04-04 | usunięcie wzmianki o przestarzałym operatorze <> |
Widać, że zmiany są rzadkie i zwykle małe: pierwsze lata przyniosły dużo poprawek, a ostatnie lata głównie drobne porządki. PEP 8 nie przechodzi „wielkich wydań”, bo jego zasady były stabilne od lat.
Jak PEP 8 wiąże się z wersjami Pythona i ich wydawaniem?
Cykl wydań, który znasz z Pythona, opisuje inny dokument, PEP 602. Według niego nowa wersja Pythona (3.x) wychodzi co 12 miesięcy, w październiku. Każda wersja ma 2 lata pełnego wsparcia i kolejne 3 lata poprawek bezpieczeństwa, czyli łącznie 5 lat. Prace nad jedną wersją trwają około 17 miesięcy i obejmują fazy:
| Etap | Czas trwania | Co się dzieje |
|---|---|---|
| Nakładka na poprzednią wersję | ok. 5 miesięcy | trwa stabilizacja poprzedniej wersji |
| Alfy | ok. 7 miesięcy | dodawane są nowe funkcje |
| Bety | ok. 3 miesiące | nowych funkcji już nie dodaje się (zamrożenie przy Beta 1) |
| Kandydaci do wydania (RC) | ok. 2 miesiące | ostatnie poprawki i wydanie |
Aktualny stan wersji (dane z oficjalnego przewodnika dla programistów Pythona z listopada 2026):
| Wersja | Pierwsze wydanie | Koniec wsparcia (zaplanowany) |
|---|---|---|
| 3.15 | 2026-10-09 | 2031-10 |
| 3.14 | 2025-10-07 | 2030-10 |
| 3.13 | 2024-10-07 | 2029-10 |
| 3.12 | 2023-10-02 | 2028-10 |
| 3.11 | 2022-10-24 | 2027-10 |
| 3.10 | 2021-10-04 | zakończone 2026-10-01 |
Prace nad kolejną wersją, Pythonem 3.16, już trwają. Według harmonogramu z PEP 826 pierwsza alfa wyszła 13 października 2026 roku, zamrożenie funkcji (Beta 1) przypada na 4 maja 2027, a wydanie planowane jest na 5 października 2027. Daty zaplanowane mogą się jeszcze zmienić.
Co z tego wynika dla PEP 8? Nowa wersja Pythona nie oznacza nowej wersji PEP 8. Zmiany w języku, np. nowa składnia, mogą z czasem sprawić, że dokument dostaje dopisek albo poprawkę (tak było z adnotacjami po PEP 484), ale nie dzieje się to automatycznie w rytmie październikowych wydań. Jeśli używasz najnowszego Pythona, wystarczy, że znasz aktualną wersję PEP 8 oraz konfigurację swoich narzędzi.
Co dalej?
Jeśli dopiero zaczynasz, zobacz, dlaczego Python bywa polecany jako pierwszy język, a o kolejnych krokach rozwoju przeczytasz w artykule o ścieżkach rozwoju w Pythonie. Przed rozmową kwalifikacyjną przejrzyj najczęstsze pytania rekrutacyjne z Pythona, a pracę z typami i walidacją danych w nowoczesnym kodzie pokazuje artykuł o Pydantic. Jeśli w Twoim kodzie coś nie działa, pomoże debugowanie w Pythonie.
Pythona używamy też w naszej ścieżce AI Engineer, czyli 6-miesięcznym kursie z mentorem, w którym budujesz projekt oparty na modelach językowych: od pierwszego skryptu, przez wyszukiwanie i agentów, po wdrożenie. W takim projekcie czytelny, spójny kod ma duże znaczenie, bo rozwija się go miesiącami i wraca do niego wiele razy. Polecamy ją, jeśli chcesz wykorzystać Pythona w pracy z AI.
Jeśli chcesz nauczyć się pisać czytelny kod w Pythonie pod okiem mentora, zobacz naszą ścieżkę Python.


