Python šel dlouhou dobu mimo mne. Byl jsem přesvědčen, že Perl je pro mé potřeby dostačující. Nakonec jsem se ale nechal zviklat vyprávěním o kvalitách a přednostech Pythonu. Rozhodl jsem se blíže ho prozkoumat a zkusit si v něm něco napsat. Nejprve krátké zhodnocení.
S Perlem se dnes můžeme setkat na každém systému typu Unix/Linux. Python dosud není takto široce akceptován a unixoví administrátoři jsou nuceni jej ručně instalovat. V Linuxu je Python podobně jako Perl většinou standardní součástí distribuce.
Perl tradičně exceluje v oblasti systémového programování. Zejména proto, že hlavně z těchto důvodů byl vytvořen a velmi se osvědčil. Existuje již od roku 1987. Potřebné nástroje pro systémovou správu jsou v Perlu přímo vestavěny nebo se vyskytují jako moduly. Postupem času ale obliba Perlu klesá na vrub Pythonu a dalších skriptovacích jazyků s modernějšími vlastnostmi. Python, který vznikl v roce 1990, umožňuje mnohem lepší podporu programovacích technik, jako je objektové a funkcionální programování. Prakticky to znamená čitelnější a tedy snáze udržovatelný kód.
Vlastnosti Perlu:
- je na všech Unixech
- je starší, a tudíž ho zná více lidí
- poskytuje pouze možnost pseudo-objektového psaní
Vlastnosti Pythonu:
- je lépe čitelný
- je nativně objektový
Vývojové prostředí
Skalní příznivci příkazové řádky budou určitě souhlasit, že pro vývoj není nezbytně nutné pracovat ve vývojovém prostředí. Většina vystačí s funkcí print
a debuggerem gdb
. Přesto je ale dobré mít k dispozici vývojové prostředí integrující pohodlné ladění, hledání v dokumentaci, zvýrazňování klíčových slov zdrojového kódu atd. Pro platformu Perl/Linux bylo prostředí celkem úzký profil. Existují komerční řešení jako například Komodo od firmy ActiveState, ale jediné mně známé „open source“ řešení byl javový Eclipse s pluginem EPIC. Eclipse je ale bohužel velmi náročný na systémové zdroje. Naštěstí zde nyní máme Kdevelop, který postupně zlepšuje podporu skriptovacích jazyků. Platforma Python/Linux je na tom lépe. Máme tu výtečné nástroje Eric3 nebo SPE, které jsou „open source“ řešením s dostatečnou kvalitou.
Začátek kódování
Pro mne, vývojáře v Perlu s delší zkušeností, představoval začátek psaní v Pythonu hlavně šok z absence závorek, středníků a nutnosti striktně zachovávat formát kódu. Člověk si ale brzy zvykne. Základní syntaxe je jednoduchá, a tak po chvíli experimentování nic nebrání začít s vlastním kódováním. Dalším krokem je zpravidla prozkoumání nápovědy a základních modulů. Perlovský perldoc
je u Pythonu nahrazen programem pydoc
. Schopnosti pydocu jsou trochu větší. Například může sloužit jako dokumentační server, vývojáři pak mohou použít pro prohlížení dokumentace prohlížeč. Z praktického hlediska jediného uživatele mi ale přišly obě varianty víceméně podobné. Někdy se v systému nachází více verzí Pythonu, takže nesmíte například zapomenout, že program pydoc se lehce liší od pydoc2.4.
Shell
Použitelným se také ukázal pythonský shell, který nejen usnadňuje počáteční pokusy, ale také jej lze využít pro administrátorskou práci. Na rozdíl od Pythonu, kde je shell standardní součástí instalačního balíku, Perl dlouhou dobu vlastní shell neměl nebo se velmi dlouho nacházel ve stádiu vývoje. V současnosti jich má hned několik. Například zoid nebo psh.
Praktické postřehy
Během práce jsem narazil na některé věci, jež jsou v obou jazycích realizovány rozdílným způsobem.
- Komentáře
Jednořádkové komentáře jsou stejné. Rozdíl přijde, chcete-li zakomentovat větší část kódu. V Perlu musíte použít dvojici
=begin
,=cut
, což je ale spíše určeno pro dokumentování kódu. V Pythonu jsou implementovány pomocí tří uvozovek, což se mi jeví jako praktičtější. - Regulární výrazy
Regulární výrazy jsou jednou z výborných stránek Perlu. Lze myslím tvrdit, že to byl právě Perl, který se povedenou implementací postaral o jejich masové využití. Také se postaral o jejich rozšíření, které se uchytilo a proniklo do GNU verzí tradičních nástrojů (např. sed, grep) a dalších jazyků. Pro práci s regulárními výrazy (RE) se v Pythonu využívá modul re. Práce s RE se pak do značné míry podobá způsobu práce v C nebo C++. Není to tedy přímočaré jako v Perlu. Na druhou stranu se i Python pokusil RE rozšířit. Příklad použití RE:
import string, re
import fileinput
filename = "file.txt"
file_h = open(filename)
re_obj = re.compile(r"^(\w+):(\w+):(\w+):(.*):(.*):(.*):(.*)$")
for line in fileinput.input(filename):
line = string.strip(line)
if re_obj.match(line):
obj = re_obj.search(line)
all_groups = obj.groups()
print "Tablename: ", obj.group(1)
file_h.close()
Následuje příklad v Perlu:
open(INFILE, $file) or err("Unable open file: ". $!);
while (defined(my $line = <INFILE>)) {
chomp $line;
next if $line =~ m/^$/;
next if $line =~ m/^\s+$/;
if ($line =~ m/^(\w+);(\w+);(\w+);(\d{1,3});(\w|-);(.*);(.*)$/) {
$xorder = sprintf("%03d", $4);
$ins_val = $6;
}
}
close(INFILE);
Použití v Perlu se zdá přímočařejší. A nyní ke zmiňovanému pythonskému rozšíření. Je patrné z následující řádky.
reobj = re.compile(r"^(?P<tablename>\w+);(?P<colname>\w+);(?P<coltype>\w+);(?P<order>\d+); (.*)$")
K jednotlivým prvkům výrazu můžeme přistupovat pomocí definovaných názvů. Při vlastním přístupu si pak nemusíme pamatovat pořadí, ale použijeme náš název. Například: order = obj.group('order')
.
- Složitější datové struktury
Velmi praktické jsou perlovské hashe, kterým se v Pythonu říká dictionary. Obecně pak asociativní pole. Při přechodu z Perlu jsem narazil na nutnost inicializovat pythonský dictionary. Tato věc není v Perlu nutná. Z hlediska čistoty stylu psaní je ale lepší každou proměnnou inicializovat. Nicméně Perl to dělá za vás. Další struktury, například pole, jsou víceméně totožné, ale pythonovský objektový přístup mi připadá propracovanější. Máme tu funkce append, extend, insert nebo tofile, které si v Perlu musíme nahradit vlastním kódem. Příklad ilustrující použití dictionary a regulárních výrazů v Pythonu:
import re, string
import fileinput
filename = "TEST_DATA.txt"
n_cfg = {}
file_h = open(filename)
re_obj = re.compile(r"^(?P<tablename>\w+);(?P<colname>\w+);(?P<coltype>\w+);(?P<order>\d+);(.*);(.*);(.*)$")
# Read the file
for line in fileinput.input(filename):
line = string.strip(line)
if re_obj.match(line):
obj = re_obj.search(line)
table_name = obj.group('tablename')
order = obj.group('order')
if not n_cfg.has_key(table_name): n_cfg[table_name] = {}
if not n_cfg[table_name].has_key(order): n_cfg[table_name][order] = {}
n_cfg[table_name][order]['COLNAME'] = obj.group('colname')
n_cfg[table_name][order]['COLTYPE'] = obj.group('coltype')
file_h.close()
# Show infos
for item in n_cfg.keys():
print "Tablename: ", item
for order in n_cfg[item].keys():
print "\tOrder: ", order, "colname: ", n_cfg[item][order]['COLNAME']
- Inkrementálni operatory
Představte si, že Python nemá operátor ++!! Musíme ho nahrazovat operátorem =+ 1, což bohužel elegance dvou plusů nedosahuje a já osobně jsem ho velmi postrádal.
Silné stránky Pythonu
Asi budu opakovat starou pravdu, kterou se můžete dočíst v mnoha podobně laděných článcích, ale dle mého názoru tkví nejsilnější stránka Pythonu v jeho objektovosti. Objektový přístup se projeví u větších projektů a nebo také při tvorbě grafických programů. Je vrozená, takže si můžeme užívat krás a pohody výjimek, což v Perlu nelze. Všechny datové typy jsou objekty, takže se zde nesetkáme s datovým typem pointer. Pointer na cosi je skryt za termínem „reference na objekt“, takže nám nic nebrání napsat následující elegantní řádky:
def nase_fce(param):
return param + 1
print nase_fce(5)
pointer_na_fci = nase_fce
print pointer_na_fci(5)
Vývojář není k objektovému kódu nucen jako v případě Javy nebo Smalltalku. Chcete-li, nemusíte objektový styl vůbec použít. Taky mám pocit, že se tu daří lépe držet krok s novými technologiemi.
Silné stránky Perlu
Perl je fantastický coby kompaktní zpracovatel textových dat. Je to jeho hlavní využití a v této oblasti exceluje. Potřebujete-li něco parsovat nebo jinak zpracovat, neváhejte. Grafické aplikace samozřejmě můžete psát také, ale podle mne se lépe udržují a píšou za použití objektového přístupu.
Vlastní zkušenosti
Jak jsem již řekl, jsou moje zkušenosti s Perlem několikanásobně větší než s Pythonem. A přesto mi přišlo kódováni v Pythonu velice snadné. Píše se lehce a postupem času čím dál tím snadněji. Jako příklad uvedu menší prográmek, který jsem se odhodlal napsat. Slouží k monitorování teploty harddisku mého notebooku pomocí parsování hlášek S.M.A.R.T. démona. Výsledek, který ilustrují následující obrazovky, jsem vytvořil během několika málo hodin. Počítaje v to zkoumání knihovny QT, ve které jsem zatím nic nenapsal. Kdo chce, nechť se podívá do zdrojového kódu nebo, jste-li uživatelé „debian-like“ systémů, můžete si to stáhnout a nainstalovat z deb balíčku. Jde to opravdu snadno. I údržba kódu po delším čase se mi v případě Pythonu zdá lepší. Podívejte se na ilustrační screenshoty
Graf vývoje teploty harddisku
Tabulková forma vývoje teploty harddisku
Doslova fascinován jsem byl pythonským modulem cheetah
, který se běžně používá pro dynamické generování HTML stránek nebo čehokoliv jiného. Funkce modulu je cosi jako Python v Pythonu, přičemž jeho hlavní využití je v dynamickém generování textu dle vnitřní logiky. Určitě ho doporučuji vaší pozornosti. Stojí za to.
Jaká je jejich budoucnost
Python se vyvíjí velice zajímavým způsobem. IronPython je dokonce akceptován samotným Microsoftem jako skriptovací jazyk nad .NET knihovnami.
U Perlu nastává změna. Jeho stáří a absence nativní podpory objektů vedla k začátku práce na Perlu 6, který je již objektový. Syntaxe Perlu 6 je značně odlišná od Perlu 5. Neznamená to ale, že staré skripty budete muset zahodit. Nový Perl je naštěstí bude umět stále interpretovat.
A dostáváme se k budoucímu společnému jmenovateli těchto i dalších skriptovacích jazyků, k Parrotu. Tento bytecode interpreter je už od počátku spojen s novým Perlem 6. Jeho jméno vzniklo v rámci aprílového žertu Larryho Walla (otec Perlu) a Guida van Rossuma (otec Pythonu), kteří ohlašovali aprílové spojení Perlu a Pythonu. Slouží k interpretování mezikódu (bytecodu), do kterého jsou skriptovací jazyky po syntaktické analýze převáděny. A jak to tedy bude konkrétně vypadat? Perl 6 a další skriptovací jazyky Python nebo Ruby budou překládány do mezikódu, který bude interpretován Parrotem. Realita je bohužel trochu fádnější. Parrot vznikl již v roce 2001 a nyní je na scéně verze 0.2.3, která implementuje pouze podmnožinu funkcionality budoucího Perlu 6. Tempo vývoje Parrotu, ale i tempo vývoje nového Perlu, mi nepřipadá příliš rychlé a na finální verzi Perlu 6 si ještě musíme chvíli počkat. Každopádně si ale budeme muset zvyknout na novou syntaxi. A jak je to s Pythonem? Tam nová syntaxe hned tak nehrozí. Ale nejásejme předčasně. Guido se nechal slyšet, že budoucí Python 3.0 s naším starým známým Pythonem také syntakticky kompatibilní nebude. Nechme se překvapit.
Závěr
Když jsem se začal zamýšlet nad celkovým shrnutím svých dojmů, nemohl jsem dospět k jednoduchému závěru. Každý z obou jazyků má svá nesporná pozitiva a snad je z textu patrné, že jsou oba vhodné na řešení různých problémů. Syntaxe Perlu 5 je snad až příliš volná a vývojář by měl pro dosažení čistějšího kódu používat „striktní“ režim a přepínač -w
. Také můžeme postrádat některé oblíbené vývojářské konstrukce jako například switch/case
. Python je z tohoto hlediska čistší. Stávající Perl preferuje větší jádro integrující téměř vše, co potřebuje systémový programátor, na rozdíl od Pythonu, který má malé jádro a velkou část funkcionality obsahují moduly. Oba jazyky mají své místo a uplatnění. Doufám, že si s pomocí tohoto článku snáze vyberete.