LINUX.ORG.RU

python3 и bytes

 


1

1

Я чего то не вкурил. Предположим есть след код:

from flask_redis import Redis
redis_store = Redis(app)
data = redis_store.get('jopa' )

data возращает текст в виде bytes. Чтобы это все сериализовать через json.dumps, я должен сделать так:

    for ind in data:
        ind1 = ind.decode("utf-8")
        odata[ind1] = data[ind].decode("utf-8")

и так делать везде, ы ?

Можно просто ind.decode(), UTF-8 — кодировка по умолчанию.

proud_anon ★★★★★ ()

ы. но можно и так:

json.dumps(dict([
    (k.decode(), v.decode())
    for k, v in data.items()
]))

anonymous ()

Вообще для таких задач лучше создавать кастомный энкодер, какой-то такой:

import json
from functools import singledispatch

@singledispatch
def prepare(obj):
    return obj

@prepare.register(tuple)
@prepare.register(list)
def _prepare_list_or_tuple(xs):
    return [prepare(x) for x in xs]

@prepare.register(dict)
def _prepare_dict(dct):
    return {prepare(k): prepare(v) for k, v in dct.items()}

@prepare.register(bytes)
def _prepare_bytes(byteval):
    return byteval.decode()

class BytesEncoder(json.JSONEncoder):
    def encode(self, o):
        return super().encode(prepare(o))

Использовать как:

In [2]: json.dumps({b'test': b'cats'}, cls=BytesEncoder)
Out[2]: '{"test": "cats"}'
holuiitipun ()
Ответ на: комментарий от holuiitipun

только это ведь лишнее усложнение:

class BytesEncoder(json.JSONEncoder):
    def encode(self, o):
        return super().encode(prepare(o))
json.dumps({b'test': b'cats'}, cls=BytesEncoder)
меньше строк если делать так:
json.dumps(prepare({b'test': b'cats'}))

anonymous ()
Ответ на: комментарий от Jopich

Гм а чем это лучше того что было во 2 ветке ?

я вот так поглядел - если нужны и строки и байты - лучше использовать вторую ветку :)

buratino ★★★★ ()
Ответ на: комментарий от anonymous

меньше строк если делать так:

Иногда нужны ещё другие возможности в енкодере.

Если хочеться сильно меньше писать, то можно:

json._default_encoder = BytesEncoder
json.dumps({b'test': b'cats'})

Но лучше так не делать =)

holuiitipun ()

Можно сделать гораздо проще:

conn = redis.Redis(decode_responses=True)

Единственное, не знаю, принимает ли этот флаг обертка из flask_redis. По идее какой-то способ передать параметры должен быть.

satanic-mechanic ()
Последнее исправление: satanic-mechanic (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.