Python – Konvence pro psaní kódu

Python – Konvence pro psaní kódu

V tomto článku jsou sepsány nejdůležitější pravidla a konvence pro psaní zdrojového kódu programů v Pythonu. Článek vychází z informací uvedených v dokumentu PEP 8 – Style Guide for Python Code (PEP je zkratka pro Python Enhancement Proposals). Nejde o překlad tohoto dokumentu, pouze o výpis těch nejdůležitějších věcí, které by měl každý kdo programuje v Pythonu znát a pokud možno se jimi i řídit.

Nedávno jsem se rozhodl, že si zlepším svoje programátorské schopnosti v Pythonu. Během učení si sepisuji poznámky, které jsem se rozhodl transformovat do série několika článků o Pythonu. Zabiji tak dvě mouchy jednou ranou. Budu mít své poznámky vždy po ruce a zároveň můžou pomoci ještě někomu dalšímu. Články nebudou psány ve formě návodů, těch najdete na internetu spousty (ať už více, či méně kvalitních). Moje články budou psány ve formě poznámek, zaměřené vždy na konkrétní vlastnost Pythonu.

Formátování

Odsazení pomocí 4 mezer.

K odsazení je možno použít tabulátory.

Pro nové projekty se doporučuje používání mezer.

Nikdy při odsazování nemíchat tabulátory a mezery!

Řádky

Maximální délka všech řádků by měla být maximálně 79 znaků. Ještě pořád je spousta zařízení, která mají limit na 80 znaků a zároveň pokud má řádek jenom 79 znaků, je možné mít více oken vedle sebe. Také se spíše vyhnete tomu, že vám editor bude zalamovat řádky, protože okno není dost široké (což způsobuje nepřehlednost kódu).

Pro delší bloky textu se doporučuje šířka řádku 72 znaků.

Prázdné řádky

Definice funkcí a tříd jsou odděleny 2 prázdnými řádky.

Definice metod uvnitř tříd jsou odděleny jedním prázdným řádkem.

Prázný řádek může být použit pro oddělení bloku souvisejících příkazů.

Používejte prázdné řádky v kódu funkcí pro naznačení logických sekcí.

Python přijímá Ctrl+L (alias ^L) znak zalomení na stránku jako bílý znak. Většina editorů používá tento znak k oddělování stránek, takže ho můžete používat k oddělení souvisejících sekcí v souboru.

Kódování

Python vždy používal ASCII nebo Latin-1 (ISO-8859-1), pro Python 3.0 a vyšší je preferovaným kódováním UTF-8.

Ne-ASCII znaky se doporučuje používat pouze v komentářích nebo dokumentačních řetězcích. V jiných případech se doporučuje používání x, u nebo U což je preferovaný způsob vkládání ne-ASCII textových řetězců.

Pro Python3.0 a výše musí být všechny identifikátory ve standardní knihovně pouze v ASCII a pokud je to možné, tak by mělo jít o anglické slova. Textové řetězce a komentáře musí být také pouze v ASCII, výjimku tvoří (a) případy testování ne-ASCII vlastností a (b) jméno autora. Autoři, jejichž jméno není psáno v latince, musí poskytnout přepis jména do latinky.

Importování

Každá importovaná knihovna by měla být uvedena na samostatném řádku.

Importy se píšou vždy na začátek souboru. (Za komentáře a dokumentační řetězce a před globální proměnné a konstanty.)

Importy by měly být seskupovány podle těchto pravidel:

  1. Standardní knihovny
  2. Související knihovny třetích stran
  3. Lokální knihovny

Mezi jednotlivé skupiny knihoven můžete vložit prázdný řádek.

Za importy se vkládá odpovídající __all__ specifikace.

Mezery ve výrazech a příkazech

Vyhněte se vkládání mezer v těchto případech:

  • V závorkách – hned po úvodní závorce a před uzavírací závorkou.
  • Před čárkou, dvojtečkou, středníkem a tečkou.
  • Před kulatou závorkou, uvozující seznam parametrů funkce.
  • Před hranatou závorkou, uvozující index nebo klíč.
  • Vložení více než jedné mezery okolo operátoru přiřazení (rovná se „=“), kvůli zarovnání do sloupce s ostatními operátory v okolních výrazech.

Ostatní doporučení:

  • Operátory: =, ==, +=, -=, ==, <>, <, >, <=, >=, in, not in, is, is not, and, or, not atd. By měly být ohraničeny jednou mezerou z obou stran.
  • Jedna mezera by měla ohraničovat i aritmetické operátory ve výrazech (+, -, * atd.).
  • Mezery neohraničují = (rovná se) pokud je použito pro nastavení pojmenovaného argumentu, nebo defaultní hodnoty parametru.
  • Více příkazů na jednom řádku je silně nedoporučováno! Výjimku tvoří kratičké výrazy s if/for/while.

Komentáře

Komentáře, které jsou v rozporu s kódem jsou horší než neokomentovaný kód.

Pokaždé, když měníte kód, si udělejte čas a upravte i komentáře.

Komentáře by měly být celé věty. Pokud jde o větu, mělo by být první písmeno velké, pokud však věta nezačíná názvem identifikátoru, který má první písmeno malé (prostě nikdy neměňte velikost písmen identifikátorů v komentářích).

Pokud je komentář krátký, nemusí končit tečkou.

Pokud je komentář složen z několika vět, měl by být rozdělen do odstavce nebo odstavců a každá věta by měla končit tečkou.

Měli byste používat dvě mezery za tečkou, která končí větu.

Pro programátory z ne-anglicky mluvících zemí: Prosím pište své komentáře anglicky, pokud si nejste na 120% jistí, že váš kód niky nebude číst člověk, který nemluví vaším jazykem.

Blokové komentáře

Každý řádek komentáře začíná znakem # a jednou mezerou (kromě případu, že je v blokovém komentáři formátovaný text).

Odstavce jsou v blokových komentářích odděleny řádkem obsahujícím jeden znak #.

Řádkové komentáře

Používejte je minimálně.

Řádkové komentáře jsou na stejném řádku jako příkaz.

Řádkový komentář by měly od příkazu dělit alespoň dvě mezery.

Komentář by měl začínat znakem # a mezerou.

Řádkové komentáře jsou většinou zbytečné a působí rušivě.

Dokumentační řetězce

Pište dokumentační řetězce pro všechny veřejné moduly, funkce, třídy a metody.

Pro neveřejné metody nejsou dokumentační řetězce nutné.

Uzavírací sekvence “”” by měla být na samostatném řádku a nejlépe by jí měl předcházet prázdný řádek.

Jednořádkový dokumentační řetězec může mít otevírací i uzavírací “”” na stejném řádku.

Jmenné konvence

Nejběžněji používané styly pojmenování:

  • b (jedno malé písmeno)
  • B (jedno velké písmeno)
  • malápísmena
  • malá_písmena_s_podtržítky
  • VELKÁPÍSMENA
  • VELKÁ_PÍSMENA_S_PODTRŽÍTKY
  • CamelCase (Velbloudí konvence)
  • mixedCase
  • Velká_První_Písmena_S_Podtržítky

Speciální formy:

  • _jedno_úvodní_podtržítko: Indikátor vnitřního užití. („from M import *“ neimportuje objekty, jejichž jméno začíná podtržítkem)
  • jedno_koncové_podtržítko_: Používáno kvůli předcházení konfliktům s klíčovými slovy Pythonu.
  • __dvojité_úvodní_podtržítko: Využívá se pro name mangling.
  • __dvojité_úvodní_a_dvojité_koncové__: Magický objekt, nebo atribut v uživatelském jmenném prostoru.

Jména, kterým se vyhnout

Nikdy nepoužívejte znaky „l“ (malé L), „O“ (velké o), nebo I (velké i) jako jednoznakové jméno pro proměnnou. V některých fontech jsou tyto znaky obtížně rozlišitelné od jedniček a nul.

Balíčky a moduly

Jména modulů by měla být krátká a psaná pouze malými písmeny. Pro zvýšení čitelnosti je možno použít podtržítka.

Jména balíčků by měla být krátká a psaná pouze malými písmeny. Podtržítka v názvu se nedoporučují.

Krátká délka a malá písmena jsou doporučována, protože některé souborové systémy nerozlišují velikost písmen a mají omezenou délku pro jméno souboru.

Třídy

Téměř bez výjimek bývají jména tříd psány pomocí VelbloudíKonvence.

Jména tříd pro neveřejné použití se navíc uvozují podtržítkem.

Výjimky

Protože výjimky mohou být třídy, používají se zde konvence pro pojmenování tříd. Nicméně by jste měli používat příponu „Error“, pokud jde o výjimku způsobenou chybou.

Funkce

Malými písmeny se slovy oddělenými podtržítky pro zvýšení čitelnosti.

Globální proměnné

Konvence jsou přibližně stejné jako u funkcí.

Argumenty funkcí a metod

V případě, že jméno argumentu koliduje s klíčovým slovem Pythonu, je lepší přidat za slovo podtržítko (print_), než používat zkratky (pr), či „mrzačit“ pravopis (prnt).

Jména metod a proměnných

Malá písmena s podtržítky oddělujícími slova pro zvýšení čitelnosti.

Jedno úvodní podtržítko pro neveřejné metody a proměnné.

Pro předejití konfliktu jmen s podtřídami používejte dvě úvodní podtržítka pro využití „name mangling“ (nenapadá mě vhodný český překlad viz.: http://en.wikipedia.org/wiki/Name_mangling#Name_mangling_in_Python)

Konstanty

Všechna písmena velká s podtržítky oddělujícími jednotlivá slova.

Návrh s ohledem na dědičnost

Je třeba se rozhodnout, zdali budou atributy (metody a proměnné) veřejné, nebo neveřejné. V případě pochybností je vhodné si uvědomit, že je jednodušší udělat z neveřejného atributu veřejný, než z veřejného neveřejný.

Název veřejného atributu by neměl začínat podtržítkem.

Pokud název atributu koliduje s rezervovaným klíčovým slovem, tak přidejte za název podtržítko.

Jednoduché datové atributy je nejlepší deklarovat jako veřejné a vyhnout se psaní komplikovaných přístupových metod.

Doporučení pro programování

Porovnání na typy jako „None“ by mělo být realizováno pomocí „is“, nebo „is not“, nikoli pomocí operátorů porovnání (==).

V případě, že chcete testovat, zda byla nějaká proměnná nebo argument, který se defaultně nastavuje na None, nastaven na jinou hodnotu, vyvarujte se psaní podmínek „if x“ místo „if x is not None“. Jiná hodnota totiž může mít typ, který je v boolenovském kontextu False (třeba jako kontejner).

Používejte výjimky založené na třídách.

Pro vyvolání výjimky používejte „raise ValueError(‘Zpráva’)“ místo staršího „raise ValueError, ‘Zpráva’“. Použití závorek umožňuje zalomení dlouhé zprávy na další řádek bez explicitního uvedení znaku „“ symbolizujícího, že příkaz pokračuje na dalším řádku.

Pokud zachytáváte výjimku, uvádějte jméno výjimky, místo použití obecného „except:“. Obecné except totiž zachytí všechny výjimky a to může způsobovat problémy. Například můžete zachytit výjimku KeyboardInterrupt vyvolanou stisknutím Ctrl+C, na základě které uživatel očekává, že se program ukončí, ale vy místo ukončení provedete jinou akci, protože jste původně měli v úmyslu zachytit něco jiného.

Pro všechny klauzule „try/except“ se snažte „try“ omezit na absolutní nezbytné minimum kódu. Předejdete tím možnosti maskování chyby, kdy vám bude výjimku vyvolávat jiný příkaz, než jste očekávali.

Používejte startswith() a endswith() místo slicingu řetězců (např.: retezec[:3]) pro kontrolu prefixů a sufixů. Je to čistší způsob, který je zároveň méně náchylný k chybám.

Při kontrole typu vždy užívejte isinstance() místo porovnávání typu přímo. Pokud chcete zkontrolovat, zda jde o typ řetězec, je třeba pamatovat na to, že obyčejný řetězec a unicode řetězec jsou rozdílné třídy, které však mají stejnou bázovou třídu „basestring“.

Pro testování prázdnosti sekvencí (string, list, tuple), využijte faktu, že prázdná sekvence je False. Místo „if len(seq)“ je lepší použít „if seq“

Neporovnávejte boolovské hodnoty vůči True nebo False pomocí operátoru porovnání (==). Místo „if greeting == True“ použijte „if greeting“

Odkazy

Originální článek „Style Guide for Python Code“ ze kterého jsem čerpal: http://www.python.org/dev/peps/pep-0008/

Comments are closed.