Čeština v Python 2.x
Obsah
- Kódování vlastního textu programu
- Kódování vstupů
- Kódování názvů souborů a adresářů
- Kódování obsahu souborů
- Kódování defaultencoding
- Praktická zkouška
- Malá písmena na velká (po česku)
- Řazení (po česku)
- Převod mezi různými znakovými sadami
- Odstranění diakritiky
- Seznamy a n-tice
- Čtení souboru utf-8 s příznakem BOM
- Čeština v input() i raw_input()
- Ukládání unicode text do souboru
- Čeština v komentářích
- Záložky, Oblíbené
Kódování vlastního textu programu
Pro správné fungování češtiny v samotném programu je třeba dodržet 3 hlavní zásady:
- Na první řádce uvést pythonovskou definici kódování, tedy např.: # -- coding: utf-8 --
- V tom stejném kodování to uložit - například v PSPadu navolit menu Formát - UTF-8 a uložit
- Před všechny řetězce dát znak 'u' (jako Unicode), tedy např.
# -*- coding: utf-8 -*- veta=u"Žluťoučký kůň pěl ďábelské ódy." print veta
Poznámka: pokud použijete kodování utf-8 není potřeba vkládat před řetězce znak "u". U všech ostatních to je nutné.
Kódování vstupů
Máte-li ve svém programu žádost na vstup od uživatele (klasicky input() či raw_input()), je hodnota vrácena v kódování, které získáte příkazem:
import sys print sys.stdin.encoding
Standardně pod Windows se jedná o cp852, pod Linuxem ...
Používáte-li jakékoliv GUI a žádáte uživatele o vstup, bude kódování s největší pravděpodobností utf-8. Jinými slovy u GUI aplikací neplatí sys.stdin.encoding.
Kódování názvů souborů a adresářů
Pracujete-li ve svém programy s názvy souborů a složek, je nejlépe žádat systém o seznamy předáváním parametru cesty s "u" (unicode). Např. u"." - aktuální adresář v unicode. Bude vrácen seznam také v kodování unicode. Pokud nepředáte parametr s "u", bude vráceno v kodování sys.getfilesystemencoding()
print os.listdir(u".") # seznam v unicode print os.listdir(".") # seznam v kodování souborového systému print sys.getfilesystemencoding() # kodování souborového systému
Kódování obsahu souborů
Platí, že se nedá "přesně určit", "automaticky detekovat", v jakém kódování, je ten který text. Dá se to "odhadnout" - umí to např. unixový program file a enca. Tyto programy se dají najít i pro Windows, ale je problém je pod Windows rozchodit (kompilace).
Nejjistější zůstává určovat kódování přesně a ručně - tedy třeba u textových editorů nechat uživatele, ať si zvolí sám, nebo u přijímaných dat si nechávat posílat i kódování.
Výjimku tvoří kódování textu v utf-8, kde platí .... doplnit .....
Kódování defaultencoding
sys.getdefaultencoding():
import sys print sys.getdefaultencoding()
sys.setdefaultencoding():
Pro správné kodování - například pro UTF vstup z SQL - stačí jediné: buď ve svém programu přidat řádky:
import sys sys.setdefaultencoding('utf-8')
nebo v adresáři site-packages vytvořit soubor sitecustomize.py se stejným obsahem. Touto úpravou se odstraní oblíbená hláška: 'ascii' codec can't encode characters. Pozn.: místo utf-8 může být i jiné, např. iso-8859-2.
Praktická zkouška
# -*- coding: iso-8859-2 -*- # tento soubor by měl být uložen v kodovani iso-8859-2 # je to důležité, aby byla shoda mezi uloženým a deklarovaným kodovanim # 'textUni' je uložen v iso-8859-2 (protože je v něm celý soubor) # a je rovnou na Unicode převeden (u na začátku řetězce), # takže nebude problém ho tisknout - nejpoužívanější způsob textUni=u'Žluťoučký kůň pěl ďábelské ódy' print "Spravne:", textUni #------------------------------------------------------- # 'text' je uložen také v iso-8859-2 (ale bez převodu na Unicode) text='Žluťoučký kůň pěl ďábelské ódy' # takže když ho chceme vytisknout správně vždy a všude # musíme ho převést na Unicode takto: print "Spravne:", unicode(text,'iso-8859-2') # nebo takto print "Spravne:", text.decode('iso-8859-2') # pokud bychom omylem nepoužili žádnou konverzi, dostaneme hatmatilku print "Spatne:", text # pokud pouzijeme špatné kodovaní, dostaneme chybu # print "Spatne, dokonce s chybou:", unicode(text,'cp1250') # převod tam a hned zpět, takže stejné jako "print text" print "Tam a hned zpet, spatne:", unicode(text,"iso-8859-2").encode("iso-8859-2")
Malá písmena na velká (po česku)
# -*- coding: cp1250 -*- import locale print u"řčššě".upper() locale.setlocale(locale.LC_ALL, "czech") print u"řčššě".upper()
Řazení (po česku)
#!/usr/bin/python # -*- coding: utf-8 -*- import locale seznam=["žízeň", "zábava", "údy", "uzel", "chlap", "čumil", "důkaz", "civil", "řetěz", "rozum", "ábel", "atom", "óda", "ovar"] locale.setlocale(locale.LC_ALL,'czech') seznam=[x.decode("utf-8") for x in seznam] seznam.sort(lambda a,b: locale.strcoll(a, b)) for slovo in seznam: print slovo
Převod mezi různými znakovými sadami
- Převod je možné dělat přes unicode kódování, tedy nejdříve převést vstupní řetězec na unicode (při znalosti použitého kodování) a pak z unicode na požadované.
vstup = file("vstup.txt", "r") vystup = file("vystup.txt", "w") for radek in vstup: radek = radek.decode('iso-8859-2').encode('cp1250') print radek, vystup.write(radek) vstup.close() vystup.close()
- Využitím modulu codecs.
import codecs vstup = codecs.open("vstup.txt", "r", "iso-8859-2") vystup = codecs.open("vystup.txt","w","cp1250") for radek in vstup: print radek, vystup.write(radek) vstup.close() vystup.close()
Odstranění diakritiky
Obyčejné řetězce:
# -*- coding: cp1250 -*- import string line="Žluťoučký kůň pěl ďábelské ódy" table=string.maketrans("áčďéěíňóřšťúůüýžÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ","acdeeinorstuuuyzACDEEINORSTUUYZ") print line.translate(table)
Unicode řetězce:
# -*- coding: utf-8 -*- import unicodedata line="Žluťoučký kůň pěl" line = unicode(line, 'utf-8') line = unicodedata.normalize('NFKD', line) output = '' for c in line: if not unicodedata.combining(c): output += c print output
Seznamy a n-tice
Seznamy a n-tice neumí samy o sobě tisknout správně češtinu u svých prvků. Je třeba procházet prvek jeden po druhým a tisknout každý zvlášť:
>>> s=["žízeň", "zábava","údy", "čumil", "důkaz"] >>> print s ['\xa7\xa1ze\xe5', 'z\xa0bava', '\xa3dy', '\x9fumil', 'd\x85kaz'] >>> for prvek in s: ... print prvek, ... žízeň zábava údy čumil důkaz >>>
Čeština v input() i raw_input()
Bohužel, použití češtiny v argumentu input() díky bugu ... není možné:
>>> vstup=raw_input(u"Zadej jméno") Traceback (most recent call last): File "<stdin>", line 1, in <module> UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in position 8: ordinal not in range(128)
Řešení je možné použitím příkazu print:
print u"Zadej jméno", vstup = raw_input()
Ukládání unicode text do souboru
...nelze. Je třeba před uložením text převést na nějaké normálnější kódování: utf8, cp1250, ....:
# -*- coding: utf-8 -*- text=u"Žluťoučký kůň pěl ďábelské ódy." f=open("Kun.txt","w") f.write(text) # způsobí error f.write(text.encode("utf8")) # ok f.close()
Čeština v komentářích
Objeví-li se kdekoliv v programu, třeba i v komentáři, český znak, je nutné uvést definici kódování, jinak získáte SyntaxError.