V jakém kódování je soubor uložen?

Tak buď se ptáme na název (jméno) souboru nebo na vlastní text, který je v souboru uložen.

Kódování jména souboru

se dá zjistit vcelku jednoznačně: sys.getfilesystemencoding( ). Jen pro doplnění, pokud funkci os.listdir() předáme parametr v Unicode, bude vrácený seznam taky v Unicode.

Kódování obsahu souboru

Kódování obsahu souboru se nedá (až na pár vyjímek ???) určit zcela jednoznačně. S vysokou mírou pravděpodobnosti se však to dá odhadovat. Více o tom na PythonUnicodeCestina. Na tento odhad existují různé prográmky (enca, file).

Následující script v Pythonu je jistě jejich slabým odvarem, přesto je náš, malý a funkční:

    # -*- coding: utf-8 -*-
    import os, sys

    def odhadKodovani(text):
        """ Funkce na urceni (odhad) kodovani textu v souboru.

        První výběr: která kodování projdou při převodu na unicode, ty by to mohly být.
        Většinou jich je ale několik. Ukládají se jako instance do seznamu.

        Druhý výběr: Prochází se seznam platných kodování z prvního výběru a pro každé se zjišťuje,
        kolik je v textu českých znaků. To, které jich má nejvíce, bude velmi pravděpodobně 
        hledané kodování.
        """

        encodings = (
            'ascii',
            'iso-8859-2',
            'cp1250',
            'cp852',
            'utf-8'
            )

        cestina=u"áčďéěíňóřšťúůýžÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ"   # snad jsem na žádné nabodeníčko nezapomněl

        class enc:
            u"Třída validních kodování"

            def __init__(self, kodovani):
                self.kodovani=kodovani    # typ kodovani
                self.pocet=0              # kolik je v textu českých znaků

        # ------ první výběr  ------------------------------------------------------ 
        encoding = []
        for e in encodings:
            try:
                unicode(text,e)
            except (UnicodeEncodeError, UnicodeDecodeError):
                pass
            else:
                encoding.append(enc(e))   # přidám do seznamu instanci s platným kodovaním

        # ---- druhý výběr ---------------------------------------------------------
        max=-1   # pokud v textu nejsou ceske znaky, toto zajisti, ze se zvolí ascii (prvni v encodings)
        for kod in encoding:
            for znak in unicode(text,kod.kodovani):
                if znak in cestina:
                    kod.pocet=kod.pocet+1
            if kod.pocet>max:
                max=kod.pocet
                maxKod=kod.kodovani

        return maxKod

    if __name__=="__main__":

        print u"Test všech souborů v aktuálním adresáři:\n", "-"*40

        seznam =[jmeno for jmeno in os.listdir('.') if os.path.isfile(jmeno)]

        for jmeno in seznam:
            text=file(jmeno).read()
            print jmeno, odhadKodovani(text)