Č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.