Internet Info, s.r.o. Lupa Root Měšec Podnikatel DigiZone Slunečnice Vitalianew Bomba Navrcholu Weblogy Jagg Woko Dobrý web Computer.cz SK: MojeLinky

Hlavní navigace

Novinky v jazyce Python 3.0

Změny provedené v Pythonu 3.0 oproti řadě 2.x jsou víc než velké. Zpětná kompatibilita byla částečně potlačena, byly protlačeny dlouho plánované funkce a některé se nyní chovají jinak. Některé kroky jsou vítané, jiné ne. Pojďme se tedy podívat na co si dát při programování a upravování starého kódu pozor.

Ukázky kódu jsou vždy pro Python 3.0. Pokud je kód pro verzi 2.5, tak k těmto ukázkám dávám poznámku o verzi.

Print je mrtev, ať žije print()

Nejdiskutovanější změnou je patrně zrušení jazykového konstruktu print a jeho nahrazení funkcí print(). Je to změna, která nám patrně zabere nejméně času.

>>> print "ahoj"
  File "<stdin>", line 1
     print "ahoj"
                ^
SyntaxError: invalid syntax
>>> print("ahoj")
ahoj 

Jako funkce nám print přináší i zajímavé maličkosti, které umí potěšit:

>>> import sys
>>> print("Chybka",file=sys.stderr)
Chybka
>>> print(1,2,3,4,5,sep="|",end=";\n")
1|2|3|4|5; 

Integer a float

Vítanou změnou, která také nebude tou náročnější, je prakticky zrušení limitů na velikost čísla. Z objektu long se stává int a tím pádem je v Pythonu pouze jeden celočíselný typ.

Python 2.5:
>>> long
<type 'long'>
>>> int
<type 'int'>

Python 3.0:
>>> long
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'long' is not defined
>>> int
<class 'int'> 

Práce s typem float je teď o něco chytřejší, než bývala. V 2.x Pythonech použití 1/2 vracelo int a 3.0 konečně vrací float.

Python 2.5
>>> type(1/2)
<type 'int'>

Python 3.0:
>>> type(1/2)
<class 'float'> 

Příznivcům starého chování stačí doplnit jedno lomítko navíc.

>>> type(1//2)
<class 'int'> 

Pohledy a iterátory

Některé funkce vracející v minulých verzích list, už tak dále nedělají a vrací tzv. pohledy neboli „views“. Pohled je iterovatelný objekt a lze ho používat stejně jako list.

>>> d = {"a":1,"b":2,"c":3}
>>> for x in d.keys():
...     print(x)
...
a
c
b 

V tomto případě metoda keys() vrací pohled a při zpracování cyklem se při použití prakticky nic nemění. Problém může nastat v případě, kdy potřebujeme něčemu předat list a máme pouze pohled. V tom případě to můžeme udělat třeba takto:

l = [x for x in d.keys()] 

Tento problém se projeví například hned, jak chceme pořadí první otočit:

>>> d.keys().reverse()
>>> for x in d:
...     print(x)
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'dict_keys' object has no attribute 'reverse' 

Jedno možné řešení:

>>> l = [x for x in d.keys()]
>>> l
['a', 'c', 'b']
>>> l.reverse()
>>> l
['b', 'c', 'a'] 

Funkce map() a filter() vrací místo listu tzv. iterátory. Funkčně se iterátory liší od pohledů tím, že po získání jedné hodnoty tuto hodnotu již nemůžeme získat znovu. Na konci je iterátor prázdný.

>>> def myfce(v):
...     return v**2
...
>>> i = map(myfce,[1,2,3])
>>> [x for x in i]
[1, 4, 9]
>>> [x for x in i]
[] 

Porovnávání

Operátory <, <=, > a >= se na rozdíl od nové verze chovají „více logicky“. Už není možné požadovat po Pythonu třeba:

Python 2.5:
>>> 1 < ''
True
>>> 1 > ''
False 

Po zavolání něčeho podobného v nové verzi nám Python vrátí výjimku:

Python 3.0:
>>> 1 < ''
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unorderable types: int() < str()
>>> 1 > ""
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unorderable types: int() > str() 

S tím souvisí o porovnávání ve funkcích sort() a sorted(). Ty nadále nedisponují argumentem cmp, kterým jim můžeme předat ukazatel na porovnávací funkci, ale mají tzv. klíč. Seřazení s ohledem na velikost písmen pak uděláme takto:

>>> s = ["abc","ABC","BcF","RGdd","aAaA"]
>>> s
['abc', 'ABC', 'BcF', 'RGdd', 'aAaA']
>>> s.sort(key=str.lower)
>>> s
['aAaA', 'abc', 'ABC', 'BcF', 'RGdd']
>>> s.sort()
>>> s
['ABC', 'BcF', 'RGdd', 'aAaA', 'abc'] 

Text vs. data

Python 3.0 používá ve všech textech unicode. Cokoli co není unicode, je označováno za data a je reprezentováno typem bytes. Unicode je teď reprezentován typem str.

>>> type("aa")
<class 'str'>
>>> type("aa".encode("cp1250"))
<class 'bytes'> 

Problém může nastat v situacích, kdy chceme z nějakého důvodu míchat typy str a bytes. V takovém případě Python 3.0 vrátí výjimku TypeError.

V Pythonu 2.x se unicode řetězce vytvářely přes funkci unicode(). Ta v 3.0 není k dipozici. S touto funkcí také zmizel zápis u"text". Pro změnu b"text" budeme používat pro zápis binárních resp. osmibitových dat.

>>> type(b"text")
<class 'bytes'>
>>> type("text")
<class 'str'> 

Vytváření neunicodových řetězců je možné i pomocí funkce bytes, které můžeme dát jako parametr cílovou znakovou sadu.

>>> bytes("čř",encoding="cp1250")
b'\xe8\xf8' 

Převod mezi znakovými sadami je podobný jako v Pythonu 2.x. Z unicodu do osmibitu a zase zpět:

>>> "ěščřž".encode("iso-8859-2")
b'\xec\xb9\xe8\xf8\xbe'
>>> "ěščřž".encode("iso-8859-2").decode("iso-8859-2")
'ěščřž' 

Pro ukládání dat do binárních souborů se používá typ bytes, pro textové se výstup převádí na výchozí znakovou sadu (v mém případě utf8).

>>> f = open("test","w")
>>> f.write("ěščř")
4
>>> f.close()
>>> f = open("test")
>>> f.read()
'ěščř'
>>> f.close() 

Zápis binárních dat vyžaduje typ bytes.

>>> f = open("test","wb")
>>> f.write("ěščř")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.0/io.py", line 1035, in write
raise TypeError("can't write str to binary stream")
TypeError: can't write str to binary stream 

Ukládáme data jako konkrétní znakovou sadu.

>>> f.write("ěščř".encode("cp1250"))
4
>>> f.close(
... )
>>> f = open("test","rb")
>>> f.read()
b'\xec\x9a\xe8\xf8'
>>> f.close() 

A po načtení je převedeme zpátky.

>>> f = open("test","rb")
>>> f.read().decode("cp1250")
'ěščř'
>>> f.close() 

Funkce open() má také argument encoding, kde můžeme konkretizovat znakovou sadu, ve které bude soubor uložen.

>>> f = open("test","w",encoding="iso-8859-2")
>>> f.write("ěščř")
4
>>> f.close()
>>> f = open("test",encoding="iso-8859-2")
>>> f.read()
'ěščř'
>>> f.close() 

Závěr

Novinek a nekompatibilit je mnoho. Podpora Pythonu 2.6 tu ještě nějaký čas bude a myslím si, že zavedením nekompatibilit se jazyk posunul zas o nějaký kus dopředu. Nic nelze navrhnout správně již od začátku a díky těmto změnám Python jen tak nezestárne a nebude nahrazen jazykem, který by jeho neduhy opravoval. Programátoři velkých aplikací postavených na Pythonu budou mít v příštích měsících případně letech co dělat, aby vychytali všechny problémy. Ty se budou lišit aplikace od aplikace, protože ne vždy musí být použit právě postižený kus kódu.

Příště se podíváme na další novinky a zkusíme si převod aplikace z Pythonu 2.x na Python 3.0 pomocí nástroje 2to3.

Odkazy

Adam Štrauch

Adam Štrauch

Adam Štrauch je redaktorem serveru Root.cz a svobodný software nasazuje jak na desktopech tak i na routerech a serverech. Ve svém volném čase se stará o komunitní síť, ve které je již přes 100 členů.

Školení: PostgreSQL efektivně

Akademie Root
  • administrace PostgreSQL
  • členění souborů, struktura databáze
  • instalace a inicializace clusteru, postinstalační nastavení
  • zálohování, obnova, export a import dat

Detailní informace o kurzu...

Ohodnoťte jako ve škole:
Průměrná známka 3,00

Přehled názorů

Závsr -> Záver
mrtka 8. 12. 2008 00:20
├ 
Re: Závsr -> Záver
anonymní uživatel 8. 12. 2008 00:26
│
└ 
Re: Závsr -> Záver
Adam Štrauch 8. 12. 2008 05:03
│
 
└ 
Re: Závsr -> Záver
anonym anonymni 8. 12. 2008 13:51
└ 
Re: Závsr -> Záver
volca 8. 12. 2008 08:54
RE: Novinky v jazyce Python 3.0
kkt 8. 12. 2008 03:10
├ 
RE: Novinky v jazyce Python 3.0
anonymní uživatel 8. 12. 2008 05:02
├ 
RE: Novinky v jazyce Python 3.0
Inkvizitor 8. 12. 2008 07:51
├ 
RE: Novinky v jazyce Python 3.0
beer 8. 12. 2008 10:44
│
└ 
RE: Novinky v jazyce Python 3.0
... 8. 12. 2008 13:29
└ 
RE: Novinky v jazyce Python 3.0
anonymní uživatel 8. 12. 2008 20:51
Pohled versus iterátor
Inkvizitor 8. 12. 2008 07:59
Faktické chyby
Jan Švec 8. 12. 2008 08:51
├ 
Re: Faktické chyby
JS 8. 12. 2008 09:41
├ 
Re: Faktické chyby
František Jahoda 8. 12. 2008 09:44
│
└ 
Re: Faktické chyby
slavíček 22. 4. 2009 16:11
├ 
Re: Faktické chyby
Jan Švec 8. 12. 2008 09:51
├ 
Re: Faktické chyby
Jehla 8. 12. 2008 13:01
├ 
Re: Faktické chyby
Petr Mach 8. 12. 2008 15:43
│
├ 
Re: Faktické chyby
anonymní uživatel 8. 12. 2008 16:03
│
└ 
Re: Faktické chyby
yossarian 8. 12. 2008 17:53
│
 
└ 
Re: Faktické chyby
Petr Mach 8. 12. 2008 20:35
└ 
Re: Faktické chyby
Adam Štrauch 8. 12. 2008 17:12
RE: Novinky v jazyce Python 3.0
Jirka 8. 12. 2008 13:34
a co % ?
belzebub 8. 12. 2008 14:01
├ 
Re: a co % ?
msk 8. 12. 2008 14:38
├ 
Re: a co % ?
Ondřej Čertík 8. 12. 2008 15:20
│
├ 
Re: a co % ?
Michal Čihař 8. 12. 2008 15:30
│
└ 
Re: a co % ?
Petr Mach 8. 12. 2008 15:46
├ 
Re: a co % ?
Sten 8. 12. 2008 15:34
├ 
Re: a co % ?
mikrom 20. 12. 2008 14:00
└ 
Re: a co % ?
mikrom 20. 12. 2008 14:28
zmeny v pythonu
brk 8. 12. 2008 14:41
├ 
Re: zmeny v pythonu
Sten 8. 12. 2008 14:53
└ 
Re: zmeny v pythonu
broukoid 8. 12. 2008 16:06
 
├ 
Re: zmeny v pythonu
me 8. 12. 2008 17:47
 
│
├ 
Re: zmeny v pythonu
Sten 8. 12. 2008 18:00
 
│
│
└ 
Re: zmeny v pythonu
Ondrej SanTiago Zajicek 8. 12. 2008 19:51
 
│
│
 
└ 
Re: zmeny v pythonu
PetrZ 8. 12. 2008 22:15
 
│
│
 
 
├ 
Re: zmeny v pythonu
xx 8. 12. 2008 22:24
 
│
│
 
 
│
└ 
Re: zmeny v pythonu
Sten 8. 12. 2008 23:53
 
│
│
 
 
│
 
└ 
Re: zmeny v pythonu
xx 9. 12. 2008 20:38
 
│
│
 
 
│
 
 
└ 
Re: zmeny v pythonu
Sten 9. 12. 2008 22:28
 
│
│
 
 
│
 
 
 
└ 
Re: zmeny v pythonu
xx 11. 12. 2008 21:29
 
│
│
 
 
│
 
 
├ 
Re: zmeny v pythonu
toj 23. 5. 2009 20:01
 
│
│
 
 
└ 
Re: zmeny v pythonu
Sten 8. 12. 2008 23:09
 
│
└ 
Re: zmeny v pythonu
JS 9. 12. 2008 07:20
 
└ 
Re: zmeny v pythonu
BrandIt 21. 1. 2009 12:52
Python udělal další krok dolů
Miloslav Ponkrác 9. 12. 2008 14:26
├ 
Re: Python udělal další krok dolů
Miloslav Ponkrác 9. 12. 2008 14:27
└ 
Re: Python udělal další krok dolů
Inkvizitor 9. 12. 2008 18:43
převod kódu
Lael Ophir 15. 12. 2008 02:59
└ 
Re: převod kódu
Sten 15. 12. 2008 18:03
 
└ 
Re: převod kódu
Lael Ophir 15. 12. 2008 19:28
       
Zasílat nově přidané příspěvky e-mailem