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

    Open source modální textový editor Helix, inspirovaný editory Vim, Neovim či Kakoune, byl vydán ve verzi 25.07. Přehled novinek se záznamy terminálových sezení v asciinema v oznámení na webu. Detailně v CHANGELOGu na GitHubu.

    Ladislav Hagara | Komentářů: 0
    včera 20:44 | IT novinky

    Americký výrobce čipů Nvidia získal od vlády prezidenta Donalda Trumpa souhlas s prodejem svých pokročilých počítačových čipů používaných k vývoji umělé inteligence (AI) H20 do Číny. Prodej těchto čipů speciálně upravených pro čínský trh by tak mohl být brzy obnoven, uvedla firma na svém blogu. Americká vláda zakázala prodej v dubnu, v době eskalace obchodního sporu mezi oběma zeměmi. Tehdy to zdůvodnila obavami, že by čipy mohla využívat čínská armáda.

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

    3D software Blender byl vydán ve verzi 4.5 s prodlouženou podporou. Podrobnosti v poznámkách k vydání. Videopředstavení na YouTube.

    Ladislav Hagara | Komentářů: 0
    14.7. 22:22 | Komunita

    Open source webový aplikační framework Django slaví 20. narozeniny.

    Ladislav Hagara | Komentářů: 0
    14.7. 16:11 | Komunita

    V Brestu dnes začala konference vývojářů a uživatelů linuxové distribuce Debian DebConf25. Na programu je řada zajímavých přednášek. Sledovat je lze online.

    Ladislav Hagara | Komentářů: 0
    14.7. 11:33 | IT novinky

    Před 30 lety, tj. 14. července 1995, se začala používat přípona .mp3 pro soubory s hudbou komprimovanou pomocí MPEG-2 Audio Layer 3.

    Ladislav Hagara | Komentářů: 26
    14.7. 10:55 | IT novinky

    Výroba 8bitových domácích počítačů Commodore 64 byla ukončena v dubnu 1994. Po více než 30 letech byl představen nový oficiální Commodore 64 Ultimate (YouTube). S deskou postavenou na FPGA. Ve 3 edicích v ceně od 299 dolarů a plánovaným dodáním v říjnu a listopadu letošního roku.

    Ladislav Hagara | Komentářů: 20
    13.7. 17:55 | Zajímavý projekt

    Společnost Hugging Face ve spolupráci se společností Pollen Robotics představila open source robota Reachy Mini (YouTube). Předobjednat lze lite verzi za 299 dolarů a wireless verzi s Raspberry Pi 5 za 449 dolarů.

    Ladislav Hagara | Komentářů: 17
    11.7. 16:44 | Komunita

    Dnes v 17:30 bude oficiálně vydána open source počítačová hra DOGWALK vytvořena v 3D softwaru Blender a herním enginu Godot. Release party proběhne na YouTube od 17:00.

    Ladislav Hagara | Komentářů: 3
    11.7. 14:55 | Humor

    McDonald's se spojil se společností Paradox a pracovníky nabírá také pomocí AI řešení s virtuální asistentkou Olivii běžící na webu McHire. Ian Carroll a Sam Curry se na toto AI řešení blíže podívali a opravdu je překvapilo, že se mohli přihlásit pomocí jména 123456 a hesla 123456 a získat přístup k údajům o 64 milionech uchazečů o práci.

    Ladislav Hagara | Komentářů: 16
    Jaký je váš oblíbený skriptovací jazyk?
     (59%)
     (26%)
     (7%)
     (3%)
     (1%)
     (1%)
     (4%)
    Celkem 398 hlasů
     Komentářů: 16, poslední 8.6. 21:05
    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: 663×

    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.