abclinuxu.cz AbcLinuxu.cz itbiz.cz ITBiz.cz HDmag.cz HDmag.cz abcprace.cz AbcPráce.cz
Inzerujte na AbcPráce.cz od 950 Kč
Rozšířené hledání
×
    dnes 21:22 | Nová verze

    Byla vydána (𝕏) listopadová aktualizace aneb nová verze 1.96 editoru zdrojových kódů Visual Studio Code (Wikipedie). Přehled novinek i s náhledy a animovanými gify v poznámkách k vydání. Ve verzi 1.96 vyjde také VSCodium, tj. komunitní sestavení Visual Studia Code bez telemetrie a licenčních podmínek Microsoftu.

    Ladislav Hagara | Komentářů: 0
    dnes 16:55 | Nová verze

    OpenMandriva ROME, tj. průběžně aktualizovaná (rolling) edice linuxové distribuce OpenMandriva, byla vydána ve verzi 24.12.

    Ladislav Hagara | Komentářů: 0
    dnes 02:11 | Nová verze

    U příležitosti oslav sedmi let prací na debianím balíčku vyšlo GPXSee 13.33. Nová verze přináší rychlejší vykreslování vektorových map a vylepšení/doladění nového stylu pro OpenAndroMaps/Mapsforge mapy. Kdo by rád OSM mapy v "prémiovém" barevném schématu a nechce čekat až nová verze dorazí do jeho distribuce, nalezne zdrojové kódy na GitHubu.

    Martin Tůma | Komentářů: 28
    včera 23:44 | IT novinky

    Tým Google Quantum AI představil kvantový čip Willow se 105 qubity.

    Ladislav Hagara | Komentářů: 1
    včera 23:00 | Nová verze

    Byla vydána nová verze 257 správce systému a služeb systemd (GitHub).

    Ladislav Hagara | Komentářů: 0
    včera 22:11 | Nová verze

    RPCS3 (Wikipedie), tj. open source emulátor Sony PlayStation 3, nově oficiálně běží také na architektuře arm64. Podporován je Apple Silicon (YouTube) je i Raspberry Pi 5 (YouTube).

    Ladislav Hagara | Komentářů: 0
    včera 14:55 | IT novinky

    Jaký byl rok 2024 ve vyhledávání Googlu? Mistrovství světa v hokeji, triumf Davida Pastrňáka, Robert Fico nebo loučení s herečkou Simonou Postlerovou. To jsou některá z témat, která letos nejvíce rezonovala ve vyhledávání na Googlu. Češi s velkým zájmem zjišťovali, proč je přestupný rok, a s podobnou intenzitou hledali důvod absence Zdeňka Chlopčíka ve StarDance. Kompletní žebříčky včetně globálních a další zajímavosti.

    Ladislav Hagara | Komentářů: 2
    včera 13:00 | IT novinky

    Chatbot Grok AI je nově pro uživatele sítě 𝕏 zdarma (návod). S omezením 10 zpráv za dvě hodiny a tři obrázky za den.

    Ladislav Hagara | Komentářů: 0
    včera 05:33 | Nová verze

    GNU Shepherd (Wikipedie) dospěl do verze 1.0.0. Po 21 letech. Jedná se o init systém a správce služeb napsaný v Guile Scheme. Původně se jmenoval GNU dmd (Daemon managing Daemons). Používá se v systému GNU Guix.

    Ladislav Hagara | Komentářů: 31
    včera 03:33 | Nová verze

    GNUnet (Wikipedie) byl vydán v nové major verzi 0.23.0. Jedná se o framework pro decentralizované peer-to-peer síťování, na kterém je postavena řada aplikací.

    Ladislav Hagara | Komentářů: 0
    Rozcestník

    Dotaz: Python - Pickle a shelve a kódování

    9.12.2013 20:12 alfonz mucha
    Python - Pickle a shelve a kódování
    Přečteno: 652×

    Dobrý den,

    mám tady takový dost specifický dotaz na Python a pickle/shelve. Mám kód který bych chtěl udělat pro python2 a python3. Na první pohled se zdá, že vše správně funguje, jenže po otevření dat na python 3 se objevuje chyba v kódování, která ani nejde moc dobře vyřešit.

    python2 > vytvoření souboru

    import shelve
    try:
        import dumbdbm as dumb
    except:
        from dbm import dumb

    db = dumb.open('/tmp/test',flag='c')
    database = shelve.Shelf(db,writeback=True)
    database['aa'] = {"ščř":2343, 'aaa3':'šřdd'}
    database.sync()
    database.close()

    python3 > otevření souboru

    import shelve
    try:
        import dumbdbm as dumb
    except:
        from dbm import dumb

    db = dumb.open('/tmp/test',flag='c')
    database = shelve.Shelf(db,writeback=True)
    database['aa']

    Traceback (most recent call last):
      File "/usr/lib/python3.2/shelve.py", line 111, in __getitem__
        value = self.cache[key]
    KeyError: 'aa'

    During handling of the above exception, another exception occurred:

    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/usr/lib/python3.2/shelve.py", line 114, in __getitem__
        value = Unpickler(f).load()
    UnicodeDecodeError: 'ascii' codec can't decode byte 0xc5 in position 0: ordinal not in range(128)

    Chyba je dle mého špatně vyřešitelná na úrovni kódu vlastního a je možné jí řešit upravením __getitem__()

    /usr/lib/python3.2/shelve.py
    /usr/lib/python3.3/shelve.py > Shelf v částí Unpickler(), kde chybí kódování. Do Shelf předat kódování nejde.

    def __getitem__(self, key):
        try:
            value = self.cache[key]
        except KeyError:
            f = BytesIO(self.dict[key.encode(self.keyencoding)])
            value = Unpickler(f,encoding="???").load()
            if self.writeback:
                self.cache[key] = value
        return value

    Upravením funkce __getitem__() na na "UTF-8" funguje

    from pickle import Pickler, Unpickler
    from io import BytesIO
    def getitem(database, key):
        try:
            value = database.cache[key]
        except KeyError:
            f = BytesIO(database.dict[key.encode("UTF-8")])
            value = Unpickler(f,encoding="UTF-8").load()
            if database.writeback:
                database.cache[key] = value
        return value

    from pickle import Pickler, Unpickler
    from io import BytesIO
    getitem(database, 'aa')
    {'ščř': 2343, 'aaa3': 'šřdd'}

    Takže teď nevím, jakým způsobem bych to měl řešit.. mám dělat nějaký wrapper nebo to je normální chování?? Někdo znalý Pythonu poraďte.

    Odpovědi

    9.12.2013 20:17 alfonz mucha
    Rozbalit Rozbalit vše Re: Python - Pickle a shelve a kódování
    Blbé je, že většina tříd/dat, které se ukládají je potřeba právě otevírat jak v python2/python3 tak obsahují hodně unicode. Napadlo, mě ještě nějak upravit pickle protocol? Ale to asi také nepomůže, že ano?
    Fuky avatar 10.12.2013 13:04 Fuky | skóre: 52 | blog: 4u
    Rozbalit Rozbalit vše Re: Python - Pickle a shelve a kódování
    Příloha:
    Na Debianu s Pythonem 3.2.3-7 kód funguje bez problémů. Konstruktor Shelf má defaultně nastavený parametr keyencoding="utf-8", který se používá pro nastavení self.keyencoding.
    10.12.2013 15:31 alfonz mucha
    Rozbalit Rozbalit vše Re: Python - Pickle a shelve a kódování
    Ano... ale to je pouze pro otevření textu > ale ne pro pickle. Ta chyba se objeví až pro pickle jak je ukázáno.

    kód v Pythonu 2 zapsat soubor do /tmp/ a pak zkusit otevřít v pyhtonu 3. Takto jste to zkoušel?
    Fuky avatar 11.12.2013 11:26 Fuky | skóre: 52 | blog: 4u
    Rozbalit Rozbalit vše Re: Python - Pickle a shelve a kódování

    Omlouvám se, máte pravdu, řešil jsem to v rychlosti.

    Lze to vyřešit i bez zásahu do standartního modulu:

    def u(string):
        if (sys.version_info[0] < 3):
            return unicode(string, "utf-8")
    
        return string
    
    ...
    
    database = shelve.Shelf(db, protocol=2, writeback=True)
    
    ...
    
    database['aa'] = {u('ščř'): 2343, 'aaa3': u('šřdd')}
    

    Zkoušel jsem to s Pythonem 2.5 a 3.2.

    11.12.2013 12:12 alfonz mucha
    Rozbalit Rozbalit vše Re: Python - Pickle a shelve a kódování
    To je sice také dobré řešení, ale znamená to úpravu velkého množství kódu. Jak jsem psal potřebuji to pro další sérii tříd a to by znamenalo velké množství duplicity kódu.

    Přemýšlím, jestli to není možné reportovat jako chybu/podivné chování > v pythonu 2 totiž Pickle encoding parametr neměl. Avšak nově od asi od 3.2 má parameter encoding="acsii". Pokud by se do shelve přidal parametr/ či se připojil do části Unpickler, tak by to bylo řešitelné více systémově a bylo by to výhodnější i pro další projekty, které nepracují pouze s "ascii".

    Na druhou stranu nevím, jestli to je špatné chování nebo není.
    Fuky avatar 11.12.2013 14:03 Fuky | skóre: 52 | blog: 4u
    Rozbalit Rozbalit vše Re: Python - Pickle a shelve a kódování

    Pak lze ještě použít "obezličku", kterou jsi nastínil:

    from pickle import Pickler, Unpickler
    
    try:
        from io import BytesIO
    except:
        pass
    
    class MyShelf(shelve.Shelf):
    
        def __init__(self, db):
            shelve.Shelf.__init__(self, db, protocol=2, writeback=True)
    
        def __getitem__(self, key):
            if (sys.version_info[0] < 3):
                return shelve.Shelf.__getitem__(self, key)
    
            try:
                value = self.cache[key]
            except KeyError:
                f = BytesIO(self.dict[key.encode(self.keyencoding)])
                value = Unpickler(f, encoding="utf-8").load()
                if self.writeback:
                    self.cache[key] = value
            return value
    
    ...
    
    database = MyShelf(db)
    database['aa'] = {'ščř':2343, 'aaa3':'šřdd'}
    

    Případně lze překrýt metodu __setitem__(), v Pythonu 2, tak aby všechny řetězce převedla na unicode řetězce.

    Také mi přijde, že by bylo šikovné mít možnost nastavit kódování přímo v objektu Shelf, vzhledem k tomu, že metody, které volá tento parametr přijímají.

    11.12.2013 18:41 alfonz mucha
    Rozbalit Rozbalit vše Re: Python - Pickle a shelve a kódování
    Tusite jak spravne poslat zadost na python buglist? Ma s tim nekdo zkusenosti? Pripadne tusite jestli to lze podat jako zadost na vylepseni? Nebo je to zbytecne
    Fuky avatar 12.12.2013 11:25 Fuky | skóre: 52 | blog: 4u
    Rozbalit Rozbalit vše Re: Python - Pickle a shelve a kódování
    10.12.2013 15:33 alfonz mucha
    Rozbalit Rozbalit vše Re: Python - Pickle a shelve a kódování
    Třída Unpickler() má totiž také parameter a tam je encoding="ascii" Což pro obvykle data bez parameteru encoding "utf-8" neotevře

    Založit nové vláknoNahoru

    Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

    ISSN 1214-1267   www.czech-server.cz
    © 1999-2015 Nitemedia s. r. o. Všechna práva vyhrazena.