Как Вы выражаете двоичные литералы в Python?

Я столкнулся с этой проблемой, когда попытался сохранить модель Peewee в PostgreSQL JSONField.

После долгой работы, вот общее решение.

Ключ к моему решение проходит через исходный код Python и понимает, что документация по коду (описанная здесь здесь ) уже объясняет, как расширить существующий json.dumps для поддержки других типов данных.

Предположим, что вы иметь модель, которая содержит некоторые поля, которые не могут быть сериализованы для JSON, и модель, которая содержит поле JSON, первоначально выглядит следующим образом:

class SomeClass(Model):
    json_field = JSONField()

Просто определите пользовательский JSONEncoder, как это:

class CustomJsonEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, SomeTypeUnsupportedByJsonDumps):
            return < whatever value you want >
        return json.JSONEncoder.default(self, obj)

    @staticmethod
    def json_dumper(obj):
        return json.dumps(obj, cls=CustomJsonEncoder)

А затем просто используйте его в своем JSONField, как показано ниже:

class SomeClass(Model):
    json_field = JSONField(dumps=CustomJsonEncoder.json_dumper)

Ключом является метод default(self, obj) выше. Для каждой жалобы ... is not JSON serializable, которую вы получаете от Python, просто добавьте код для обработки типа unserializable-to-JSON (например, Enum или datetime)

Например, вот как я поддерживаю класс, наследующий от Enum:

class TransactionType(Enum):
   CURRENT = 1
   STACKED = 2

   def default(self, obj):
       if isinstance(obj, TransactionType):
           return obj.value
       return json.JSONEncoder.default(self, obj)

Наконец, с помощью кода, реализованного, как описано выше, вы можете просто преобразовать любые модели Peewee в объект JSON-seriazable, как показано ниже:

peewee_model = WhateverPeeweeModel()
new_model = SomeClass()
new_model.json_field = model_to_dict(peewee_model)

Хотя приведенный выше код был (несколько) специфичен для Peewee, но я думаю:

  1. Он применим к другим ORM (Django и т. д.) вообще
  2. . Кроме того, если вы понимаете, как работает json.dumps, это решение также работает с Python (без ORM) вообще

. Все вопросы, пожалуйста, публикуйте в разделе комментариев. Спасибо!

336
задан Jim Fasarakis Hilliard 13 March 2017 в 03:47
поделиться

4 ответа

Для reference— будущее возможности Python:
Запуск с Python 2.6 можно выразить двоичные литералы с помощью префикса 0b или 0B:

>>> 0b101111
47

можно также использовать новое мусорное ведро функция для получения двоичного представления числа:

>>> bin(173)
'0b10101101'

версия Разработки документации: Новые функции и возможности в Python 2.6

277
ответ дан Andreas Thomas 23 November 2019 в 00:41
поделиться
>>> print int('01010101111',2)
687
>>> print int('11111111',2)
255

Иначе.

71
ответ дан dave4420 23 November 2019 в 00:41
поделиться

Насколько я могу сказать, что Python, до 2,5, только поддерживает шестнадцатеричный & восьмеричные литералы. Я действительно находил некоторые дискуссии о добавлении двоичного файла к будущим версиям, но ничему определенному.

-1
ответ дан Mark Biek 23 November 2019 в 00:41
поделиться

Я вполне уверен, это - одна из вещей, должных измениться в Python 3.0 с, возможно, мусорным ведром () для движения с шестнадцатеричным числом () и октябрь ().

РЕДАКТИРОВАНИЕ: ответ lbrandy корректен во всех случаях.

-3
ответ дан Peter Mortensen 23 November 2019 в 00:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: