Styl zápisu kódu

O čem si budeme povídat?

Komentáře

V kapitole Další posloupnosti jsme se již o komentářích bavili. Nicmén>, s komentáři lze d>lat i další v>ci. O n>kterých z nich se zde zmíním.

Informace o historii verzí

Bývá dobrým zvykem vytvořit na začátku každého souboru hlavičku. M>ly by v ní být uvedeny takové detaily, jako je datum vytvoření, jméno autora, datum poslední zm>ny, verze a obecný popis, týkající se obsahu. Často se uvádí seznam záznamů o zm>nách. Takový blok textu se uvádí formou komentáře:


# -*- coding: cp1250 -*- 
#############################
# Modul: Spam.py
# Autor: A.J.Gauld
# Datum: 1999/09/03
# Verze: Draft 0.4
u'''
Tento modul definuje třídu Spam, kterou můžeme kombinovat
s kteroukoliv jinou variantou třídy Jidlo, abychom vytvořili
zajímavé  pokrmy.
'''
###############################
# Log:
# 1999/09/01 AJG - Vytvoření souboru.
# 1999/09/02 AJG - Opravena chyba v cenové strategii.
# 1999/09/02 AJG - Tentokrát už jsem to ud>lal správn>!
# 1999/09/03 AJG - Přidána grilovací metoda (viz požadavek #1234)
################################
import sys, string, food
...

Takže když soubor poprvé otevřete, m>li byste na začátku uvid>t souhrnnou informaci o tom, k čem soubor slouží, co se b>hem času zm>nilo, kdo a kdy zm>nu provedl. Důležité je to zejména tehdy, když je soubor součástí týmového projektu, a vy potřebujete zjistit, koho se máte zeptat na v>ci kolem návrhu a zm>n. Existují nástroje pro správu verzí, které vám mohou pomoci vytváření takové dokumentace zautomatizovat, ale jejich vysv>tlování přesahuje rámec této učebnice[1].

Povšimn>te si, že jsem popis modulu vložil mezi dv> posloupnosti tvořené trojicí apostrofů. Jde o pythonovský trik známý jako dokumentační řet>zec. Za chvíli si ukážeme, jak můžeme jeho obsah zpřístupnit prostřednictvím zabudované funkce help()

Poznámka překladatele: Proti anglickému originálu se tato ukázka liší ve dvou detailech. Na prvním řádku je uveden komentář ve speciálním tvaru:

# -*- coding: cp1250 -*- 

Tento řádek pythonovskému překladači říká, že zdrojový text byl zapsán s využitím znakové sady cp1250 (známé také pod normalizovanou zkratkou windows-1250). Pokud tedy překladač narazí na znak s kódem, který leží mimo definici kódu podle normy ASCII, může ov>řit, zda jde o znak z uvedené sady (zda je v ní definován) a podle potřeby jej může převést do jiného kódování.

Druhá odlišnost spočívá v tom, že úvodní trojici apostrofů předchází písmeno u. To znamená, že se dokumentační řet>zec v dob> překladu uloží v takzvaném unicode kódování. Zjednodušen> řečeno jde o to, že se pro jeden znak vyhradí v>tší prostor, než pouhý jeden bajt. To umožní jedním kódem rozlišit mnohem více různých znaků. Typicky se pro uložení používají dva bajty, které umožňují rozlišit přibližn> 65 tisíc možností (různých znaků). Při 8bitovém kódování znaků se dá rozlišit pouze 256 možností, přičemž mnohé mají již historickými okolnostmi pevn> přid>lený význam.

Praktický dopad z obecného pohledu je ten, že při zápisu řet>zců v kódování unicode vystačíme pro všechny nám blízké (i mén> blízké) jazyky s jediným systémem kódování znaků. Pro budoucí verze Pythonu se počítá s tím, že se unicode stane jediným používaným způsobem kódování řet>zců uvnitř interpretu.

Praktický dopad z pohledu b>hu našeho programu je ten, že v případ> důsledného používání kódování unicode budou zobrazované texty vypadat stejn> při b>hu v anglicky mluvících zemích, v N>mecku, v Řecku, v Rusku... Případná databáze aplikace bude moci dohromady bez omezení kombinovat texty v libovolném jazyce. V jednom řet>zci můžeme uvést anglický text, jeho český ekvivalent, ruskou podobu zapsanou azbukou, atd.

Uv>domte si, že při zápisu zdrojového textu v 8bitovém kódování musí dojít k převodu kódování na unicode. To je možné pouze tehdy, když se ví, jaké 8bitové kódování je při zápisu zdrojového textu použito. Práv> proto je první řádek velmi důležitý. Pokud není uveden, pak si nov>jší verze Pythonu budou st>žovat v případ>, že naleznou znak s kódem v>tším, než 127.

Zakomentování nadbytečného kódu

Tato technika se často používá k izolaci chybného úseku kódu. Předpokládejme například, že program čte n>jaká data, zpracovává je, tiskne výstup a potom ukládá výsledek zp>t do datového souboru. Pokud výsledky neodpovídají našemu očekávání, pak bychom rádi zabránili zp>tnému ukládání (chybných) dat, abychom tento soubor neporušili. Odpovídající kód bychom mohli jednoduše odstranit. Mén> radikální přístup spočívá v tom, že dané řádky jednoduše zm>níme na komentář, například takto:

data = ctiData(soubor)
for polozka in data:
    vysledky.pridej(vypoctiVysledek(polozka))
tiskniVysledky(vysledky)
######################
# Následující kód zakomentujeme až do doby,
# kdy bude opravena chyba ve funkci vypoctiVysledek,
# která vyhodnocuje výslednou položku.
#
# for polozka in vysledky:
#     soubor.ulozit(polozka)
######################
print 'Konec programu'

Jakmile je chyba odstran>na, můžeme jednoduše smazat komentářové značky a kód se tím stane znovu aktivním. N>které nástroje pro editaci zdrojových textů, včetn> IDLE, definují v menu akce pro zakomentování vybraného úseku kódu, případn> k jeho pozd>jšímu odkomentování.

Poznámka překladatele: U n>kterých editorů lze k této akci využít vlastností editace sloupcových bloků. Například voln> dostupný editor jEdit vám umožní definovat sloupcový blok o nulové šířce. Jakmile začnete n>co psát, začne se chovat jako sada pod sebou umíst>ných kurzorů pro vepisování textu — vše se opisuje na všech řádcích v míst>, kde je sloupcový blok označen. Vepsáním jediného znaku '#' tedy zakomentujete celý úsek, před který jste takový sloupcový blok umístili.

Dokumentační řet>zce

Komentáře, které dokumentují, co daná funkce nebo modul d>lají, můžeme použít ve všech jazycích. Ale jen pár jazyků — jako je Python a Smalltalk — jdou o krok dále a umožňují nám dokumentovat funkci takovým způsobem, že mohou být použity v integrovaném prostředí pro realizaci interaktivní nápov>dy b>hem programování. V jazyce Python toho dosáhneme použitím """dokumentačních řet>zců""":

class Spam:
    """Maso určené ke kombinování s ostatními potravinami.
 
    Ve spojení s jinými potravinami se dají vytvořit zajímavá jídla.
    Obsahuje mnoho živin a může být připraveno mnoha různými způsoby."""
    
    def __init__(self):
        ...

print Spam.__doc__

Poznámka překladatele k českým znakům v ukázce: Pokud si bude Python st>žovat, že používáte nepovolené znaky, zkuste je nahradit česká písmenka ceskymi (bez diakritiky). K tomuto problému se ješt> vrátíme na jiných místech.

Poznámka: Dokumentační řet>zec můžeme vytisknout jako obsah speciální prom>nné __doc__. Dokumentační řet>zce mohou být definovány pro moduly, funkce, třídy a metody tříd. Vyzkoušejte například:

import sys
print sys.__doc__

Od verze 2.2 definuje Python i zabudovanou funkci help(), která vyhledá a zobrazí veškerou dostupnou dokumentaci k objektu, který je zadán parametrem. Pokud například chceme n>co zjistit o sys.exit, můžeme na pythonovském vyzývacím řádku napsat:

>>> import sys
>>> help(sys.exit)
Help on built-in function exit:

exit(...)
    exit([status])
    
    Exit the interpreter by raising SystemExit(status).
    If the status is omitted or None, it defaults to zero (i.e., success).
    If the status is numeric, it will be used as the system exit status.
    If it is another kind of object, it will be printed and the system
    exit status will be one (i.e., failure).

>>>

Pokud tento příkaz napíšete v interaktivním režimu Pythonu v DOSovém okn> a výpis zabírá více, než jednu obrazovku, zobrazuje se další text až po stisku mezerníku. Pokud chcete režim výpisu nápov>dy ukončit, stiskn>te 'q' (jako quit). Pokud příkaz help napíšete v interaktivním režimu v IDLE nebo v jiném integrovaném prostředí, pak se výpis po stránce nezastavuje. Vypíše se jednoduše celý text, protože se ke všem řádkům výpisu můžete dostat pomocí posouvací lišty na pravé stran> okna.

Poznámka překladatele: Výše zmín>né chování při výpisu nápov>dy příkazem help() si můžete vyzkoušet například na dlouhém výpisu k modulu array:

>>> import array
>>> help(array)

Příkaz help() není v Pythonu nijak utajen. Spíše naopak. Po interaktivním spušt>ní Pythonu verze 2.3.4 můžete číst výzvu k tomu, že máte napsat "help":

Python 2.3.4 (#53, May 25 2004, 21:17:02) [MSC v.1200 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>

Když napíšeme help bez závorek, Python nám napoví:

>>> help
Type help() for interactive help, or help(object) for help about object.
>>>

Odtud vidíme, že zabudovanou funkci help() (tj. se závorkami) můžeme volat i bez parametrů. V takovém případ> vstoupíme do interaktivního režimu nápov>dy. Povšimn>te si, že výpis končí vyzývací posloupností 'help>':

>>> help()

Welcome to Python 2.3!  This is the online help utility.

If this is your first time using Python, you should definitely check out
the tutorial on the Internet at http://www.python.org/doc/tut/.

Enter the name of any module, keyword, or topic to get help on writing
Python programs and using Python modules.  To quit this help utility and
return to the interpreter, just type "quit".

To get a list of available modules, keywords, or topics, type "modules",
"keywords", or "topics".  Each module also comes with a one-line summary
of what it does; to list the modules whose summaries contain a given word
such as "spam", type "modules spam".

help> 

Jak nám Python napovídá, interaktivní režim můžeme ukončit napsáním slova quit (stačí i jediné písmeno q):

help> quit

You are now leaving help and returning to the Python interpreter.
If you want to ask for help on a particular object directly from the
interpreter, you can type "help(object)".  Executing "help('string')"
has the same effect as typing a particular string at the help> prompt.
>>> 

Jak vidíte, Python nás informuje o tom, že se dostáváme op>t do interaktivního příkazového režimu.

Odsazování bloku

Jde o jedno z nejžhav>jších témat, o kterém se mezi programátory debatuje. Skoro se zdá, že každý programátor má svou vlastní představu o nejlepším způsobu odsazování kódu. Byly vypracovány n>které studie, které ukazují, že přinejmenším n>které z faktorů mají význam v>tší, než kosmetický — usnadňují nám pochopení kódu.

Důvody pro debatu jsou jednoduché. Ve v>tšin> programovacích jazyků má odsazování čist> kosmetický význam; jde o pomůcku pro čtenáře. (Pokud se týká jazyka Python, zde je odsazování nutné a má zásadní vliv na správnou funkčnost programu!) Takže například:

<script type="text/vbscript">
For I = 1 To 10
    MsgBox I
Next
</script>

Tento zápis je interpretem jazyka VBScript chápán jako naprosto shodný se zápisem:

<script type="text/vbscript">
For I = 1 To 10
MsgBox I
Next
</script>

Zápis s odsazením se nám prost> lépe čte.

Podstatné je, že odsazování by m>lo odrážet logickou strukturu kódu. M>lo by vizuáln> odrážet tok řízení v programu. Tady nám pomáhá, když bloky kódu vypadají jako bloky (v geometrickém smyslu)

XXXXXXXXXXXXXXXXXXXX
    XXXXXXXXXXXXXXXX
    XXXXXXXXXXXXXXXX
    XXXXXXXXXXXXXXXX

… což se čte lépe než následující zápis…

XXXXXXXXXXXXXXXXXXXXX
  XXXXX
    XXXXXXXXXXXX
    XXXXXXXXXXXX
    XXXXXXXXXXXX
  XXXXX

protože je lépe vid>t, co k bloku patří. Studie prokázaly výrazné zlepšení srozumitelnosti v případech, kdy odsazování odráží strukturu logických bloků. V malých příkladech, se kterými jsme se dosud setkali, se to nemusí zdát důležité. Ale jakmile začnete psát programy se stovkami a tisíci řádků, důležitost vhodného odsazování výrazn> vzroste.

Jména prom>ných

Jména prom>ných, která jsme dosud používali, nevyjadřovala žádný význam. Důvodem bylo především to, že jsme je použili jen pro ilustraci použitých technik. Obecn> je ale mnohem lepší, kdy jména vašich prom>nných vyjadřují to, co jimi chcete reprezentovat. Například v naší ukázce programu pro generování tabulek násobků jsme použili prom>nnou nasobitel, která určovala, která z tabulek se tiskne. Je to určit> smyslupln>jší, než kdybychom použili jenom n — fungovalo by to stejn> a ušetřili bychom si psaní.

Jde o kompromis mezi srozumitelností a úsilím. Obecn> se dá říct, že nejlepší je volit krátká, ale výstižná jména. Příliš dlouhá jména by nás mátla a opakované zápisy jejich správné podoby by byly obtížné. Místo prom>nné nasobitel jsme mohli použít například prom>nnou tabulka_kterou_tiskneme, ale takové jméno je mnohem delší a přitom není o nic jasn>jší.

Ukládání vašich programů

Použití příkazového řádku interpretu jazyka Python v interaktivním režimu (>>>)je velmi vhodné pro rychlé vyzkoušení nápadů. Ale jakmile činnost interpretu ukončíme, vše je ztraceno. Z dlouhodobého hlediska chceme um>t napsat programy, které budeme opakovan> spoušt>t. Dosáhneme toho vytvořením textového souboru s připonou .py. (Jde pouze o konvenci — můžete použít jakoukoliv jinou příponu. Ale podle mého názoru je dobré takové konvence dodržovat.) Poté můžeme program spustit tím že na příkazový řádek operačního systému napíšeme:

$ python spam.py

kde spam.py je jméno našeho souboru s pythonovským programem a '$' je vyzývacím znakem příkazového řádku operačního systému. (Znak '$' se používá v unixových systémech. V systémech MS Windows se jako vyzývací znak používá '>'.)

Další výhoda ukládání programů do souborů spočívá v tom, že můžete opravovat chyby, aniž byste museli znovu napsat celý fragment nebo, to se týká IDLE, aniž byste museli kurzor přesunovat nahoru, nad chybová hlášení za účelem opakovaného výb>ru kódu. IDLE umožňuje otevření souboru pro editaci a jeho současné spušt>ní prostřednictvím menu Edit|Run module.

Od této chvíle v příkladech obvykle nebudu ukazovat vyzývací posloupnost >>>. Budu předpokládat, že program zapisujete do souboru a soubor spouštíte buď z IDLE nebo z příkazového řádku shellu nebo DOSového okna, což je můj oblíbený způsob.

Poznámka pro uživatele systému Windows

Pod Windows lze v aplikaci Průzkumník nastavit vazbu pro soubory s příponou .py tak, abyste mohli pythonovské programy spoušt>t jednoduše poklepáním na ikonu souboru. Instalátor systému Python by to m>l ud>lat již dříve za vás. Můžete si to ov>řit tím, že naleznete n>jaký soubor s příponou .py a zkusíte ho takto spustit. Pokud k jeho spušt>ní dojde (a to i v případ>, že se objeví pythonovské chybové hlášení), je vazba pro příponu nastavena. Problém, se kterým se v takovém případ> pravd>podobn> setkáte, spočívá v tom, že se program spustí v DOSovém okn>, které se po dokončení programu hned zavře. N>kdy to prob>hne tak rychle, že si vytvoření DOSového okna st>ží všimnete. Problém lze vyřešit takto:

Poznámka pro uživatele systému Unix

Systém Unix se k pythonovským souborům chová jako k ostatním skriptům, proto by první řádek pythonovského skriptového souboru m>l obsahovat posloupnost #! následovanou plnou cestou k aplikaci python — do místa, kde ji máte nainstalovanou ve vašem systému. Plnou cestu můžete nalézt tak, že na příkazovém řádku shell napíšete:

$ which python

Na mém systému to pak vypadá takto:

#! /usr/local/bin/python

To vám umožní soubor spoušt>t aniž byste museli přímo volat Python. Souboru ješt> musíte příkazem chmod přid>lit příznak spustitelnosti, ale jsem si jistý, že tohle jste již v>d>li:

$ spam.py

Na moderních unixových systémech (včetn> všech distribucí systému Linux) můžete dokonce použít ješt> šikovn>jší trik, kdy zápis cesty k aplikaci můžeme nahradit zápisem /usr/bin/env/python takto:

#! /usr/bin/env/python

Tím se zajistí automatické vyhledání Pythonu mezi cestami v path. Jediná nepříjemnost, se kterou byste se pak mohli potkat, by nastala v případ>, kdy máte v systému nainstalovaných více verzí Pythonu a skript funguje pouze při použití jedné z nich. (Může například využívat zcela nový jazykový rys, který je podporován jen v poslední verzi Pythonu.) V takovém případ> je výhodn>jší zůstat u použití plné cesty k aplikaci.

Řádek #! nezpůsobí žádný problém ani při spoušt>ní pod Windows nebo Mac. Vypadá prost> jako komentář. To znamená, že tento řádek mohou do svých skriptů uvád>t i uživatelé systémů Windows nebo Mac pokud předpokládají, že by jejich skript mohl být užitečný a použitelný i v unixových systémech.

VBScript a JavaScript

Pokud chcete používat pouze VBScript a JavaScript, pak výše uvedený text můžete ignorovat. Vaše programy jste museli ukládat do souborů již dříve, protože to byla jediná možnost, jak je spustit.

Zapamatujte si

Pokud vás napadne, co by se dalo na překladu této kapitoly vylepšit, zašlete e-mail odklepnutím Tím budou do dopisu automaticky vloženy informace o tomto HTML dokumentu.

$Id: cztutstyle.html,v 1.9 2005/03/09 21:09:24 petr Exp $