Python 3 může oživit Python. Ale nemyslí si to všichni.

Od vydání Pythonu 3 na konci roku 2008 uběhlo už hodně času, přesto je to s jeho popularitou poněkud vlažné. V poslední době se dokonce začínají objevovat nové články o tom, že by se mělo pokračovat s vývojem Pythonu 2, protože Python 3 nepřináší nic převratného a přechod na něj je zbytečně náročný (ať už časově či finančně). To však může vést k roztříštění komunity a není to nejlepší vizitkou pro jazyk jako takový.

Python 3 dělá práci programátora příjemnější

Z vlastní zkušenosti můžu říct, že je pro mě Python 3 jazykem, který můžu mít rád a který mně neháže klacky pod nohy. V Pythonu 3 byly odstraněny některé nejednoznačnosti a programátor tak nemusí myslet na tolik okrajových případů, které by mohly nastat. Celkově to vede k mnohem příjemnějšímu pocitu z programování, nemluvě o nových funkcích, které do Pythonu pomalu přibývají s každou novou verzí. Z verze 3.4 určitě stojí za zmínku asyncio, které má slušný náběh k tomu, aby sloužilo jako základ nových asynchronních aplikací.

Spousta lidí si stěžuje na nedostupnost knihoven pro novou verzi, v praxi to ale často není tak špatné, jak by se mohlo zdát. Dnes je již naprostá většina těch nejpoužívanějších knihoven (alespoň webových) vydávána s podporou pro Python 3 a pro běžného vývojáře, který nepracuje s nízkoúrovňovým kódem dané knihovny, je tato podpora plně transparentní. Dobrým příkladem je Django, které běží s totožnou funkcionalitou na obou verzích jazyka a programátor většinou nepozná rozdíl.

Nutno dodat, že je zde i spousta zastaralých knihoven, které nefungují ani na nejnovější verzi Pythonu 2, převážně kvůli špatnému návrhu a nedostatku času autorů je dále udržovat. Tato skutečnost ve mně ale spíše umocňuje fakt, že s poměrem funkčních knihoven pro verzi 2 a 3 to není tak hrozné. Naopak Python 3 je v tomto směru ještě hodně čistý a nově psané knihovny pro Python 3 jsou aktivně udržovány.

Portování kódu není nadlidský úkol

Někdo to může považovat za nutné zlo, ale jednotlivé verze jazyka nejsou zase tak odlišné, aby portování zabralo úsilí, které by se nevyplatilo. Největší problém samozřejmě budou mít vývojáři, kteří v aplikaci hodně pracují s řetězci nebo s nízkoúrovňovým síťovým API. Někteří z nich si i veřejně postěžují, potom ale stejně napíší aplikaci kompatibilní s oběma verzemi jazyka. Konstruktivní komentáře jsou však tím, co posunuje jazyk dopředu a je potřeba si jich vážit. Možná by jen někdy mohly být prezentovány trochu jiným způsobem.

Existují nástroje, které si kladou za cíl usnadnit kompatibilitu pro obě verze Pythonu (six), nebo jednorázově pomoci převést kód z verze 2 na verzi 3 (2to3). Ten druhý z nich sice občas nefunguje bez manuálního zásahu, usnadní však spoustu práce a dokáže zpracovat minimálně ty změny, které bychom jinak museli roboticky přepisovat. Pokud hledáte ucelený zdroj informací o tom, jak portovat, můžete sáhnout po knize Porting to Python 3: An in-depth guide, případně po stručnějším, ale uceleném průvodci Porting to Python 3 Redux.

Řetězce v různých verzích Pythonu

V Pythonu 2 existují textové typy str a unicode, přičemž k str se interpret chová jako k binární reprezentaci řetězce, tedy téměř jako k náhodným bajtům. V praxi to potom znamená následující:

>>> len("čeština")  # str
9
>>> len(u"čeština")  # unicode
7
>>> print("čeština"[1:])  # str s nevhodně zvoleným ořezem
�eština

Toto chování může být pro začátečníka matoucí, proto se Python 3 snaží tento problém řešit tak, že nově se textové typy chovají jako textová unicode data. Pro práci s textovými daty je zde typ str, pokud potřebujeme pracovat s daty jako s bajty, je zde typ bytes. Pokud specifikujeme kódování, je možné mezi jednotlivými typy i snadno převádět. Důležitý je ale fakt, že v případě práce s textem se můžeme spolehnout na to, že se k tomuto typu budou i všechny ostatní funkce patřičně chovat. Nečekají na nás tak podobná úskalí jako v ukázce kódu výše. Sjednocení typů vedlo i ke sjednocení speciálních metod u třídy, takže namísto __str__ a __unicode__ už pro textové řetězce stačí použít univerzální __str__.

Malé věci, které dohromady dělají velký rozdíl

Ačkoliv byla velká část nových funkcí zpětně portována pro Python 2, stále zůstala funkcionalita, která je dostupná jenom v Pythonu 3. Standardní knihovna prošla sjednocením, byly odstraněny moduly jako md5 (nyní součástí hashlib), urlparse (nyní jako urllib.parse) a spousta dalších. V důsledku to vede ke zpřehlednění a odstranění duplicit. Všechny moduly standardní knihovny navíc nyní mají nativní podporu pro unicode (nově například csv).

sets jsou nyní součástí jazyka a není potřeba používat externí modul, třídy jsou implicitně vytvářeny v “novém stylu” (můžeme se vyhnout odvozování od object) a přidáním nové možnosti formátování řetězců se jazyk ještě více odděluje od vlivu jazyka C, kterým bylo předchozí formátování nepochybně inspirováno. Formátování řetězců je tímto zjednodušeno na úroveň šablon, které jsou podobné těm, které známe z webu. Tato funkcionalita byla pro svou užitečnost zpětně portována i do Pythonu 2. Osobně považuji za velmi užitečnou i integraci virtuálních prostředí (virtualenv) přímo do standardní knihovny, protože to usnadňuje práci s knihovnami různých verzí a umožňuje vytvářet “sandboxy” pro různé projekty.

Větší využití iterátorů

V Pythonu 2 jsme byli zvyklí na range a xrange, zip a itertools.izip, filter a itertools.ifilter. Všechny se používaly ke stejnému účelu, ale každá verze měla svá specifika. Python 3 používá pouze range, zip a filter, které se nově chovají jako iterátory. Nemusíme se tak bát použít následující zápis:

is_even = lambda n: n % 2 == 0
even_numbers = filter(is_even, range(10**100))

with open('even_numbers.txt', 'w') as f:
    for number in even_numbers:
        f.write('{}\n'.format(number))

Zatímco Python 2 na tomto kódu skončí s OverflowError: range() result has too many items, Python 3 tento kód zpracuje a začne zapisovat sudá čísla do souboru. Dokonce i při změně na xrange a itertools.ifilter Python 2 skončí s chybovou zprávou OverflowError: Python int too large to convert to C long, to kvůli implementačnímu detailu funkce xrange. Příklad sám o sobě příliš užitečný není (jedná se spíše o ukázku filter a range), změna na iterátory má však v praxi mnoho uplatnění. Díky implementaci PEP 380  do Pythonu 3.3 je navíc možné tyto funkce využít i v kombinaci s yield from syntaxí. V interaktivním shellu navíc zůstala zachována čitelnost:

>>> range(100)
range(0, 100)

Nebojte se Python 3 použít pro svůj nový projekt

Python 2 pro stávající projekty funguje dobře a není nutností přecházet na novou verzi. Letos byla oznámena podpora pro Python 2 až do roku 2020. Pokud ale plánujete váš projekt udržovat dlouhodobě, začnete nad přechodem na Python 3 minimálně přemýšlet. Nebo se alespoň pokuste psát kód tak, aby byl kompatibilní s Python 3. Pokud si chcete otestovat závislosti vašeho projektu, můžete použít nástroj caniusepython3.com. Nová verze Pythonu 2 se však neočekává.

Pro zcela nový projekt by měl být Python 3 jasnou volbou. Pokud váháte a zatím jste v Pythonu 3 nic nezkusili, doporučuji shlédnout loňské video z Pycon 2013: Python 3.3: Trust Me, It’s Better than 2.7.

A věřte mi, je lepší než 2.7.

Článek je založen na osobních názorech autora, doplněných autory Python 3 can revive Python a How keep Python 3 moving forward.

 

Vyvíjím webové aplikace v Pythonu, dříve jako CTO v abdocu, dnes v Twisto.cz, kde se snažíme změnit platby online na jedno kliknutí. Mám rád nové technologie a nebojím se skočit po hlavě do ještě neprobádaného. 

Komentáře: 21

Přehled komentářů

Ondřej Důvod
Viktor Stískala
Ondřej Re:
Bruce Re:
sachy
Bruce Re:
Miloslav Ponkrác Re:
kotekl Python 2.7
jiri.vrany Re: Python 2.7
pb Unicode :-(
rbt Zbytecny prechod
rbt Re: Zbytecny prechod
Miloslav Ponkrác Re: Zbytecny prechod
rbt Re: Zbytecny prechod
Viktor Stískala Re: Zbytecny prechod
Tester2 Novacik
Miloslav Ponkrác Re: Novacik
Martin Prokeš
snajpa Python...
Miloslav Ponkrác Re: Python...
Petr
Zdroj: https://www.zdrojak.cz/?p=12302