Определите атрибут класса данных с зарезервированным словом «class» и сериализуйте его

#python #dictionary #reserved-words #python-dataclasses

#python #словарь #зарезервированные слова #python-классы данных

Вопрос:

Хорошо, я пытаюсь определить класс данных для постановки задания в очередь в redis для работника sidekiq, спецификация полезной нагрузки sidekiq требует некоторых атрибутов что-то с этим форматом:

 {
  "class": "SomeWorker",
  "queue": "default"
  "jid": "b4a577edbccf1d805744efa9", // 12-byte random number as 24    char hex string
  "args": [......],
  "created_at": 1234567890,
  "enqueued_at": 1234567890
 }
 

Итак, я определяю класс данных в своем коде на python:

 @dataclass
class PusherNotificationJob:
   args: Any = None
   queue: str = "default"
   jid: str = secrets.token_hex(12)
   retry: bool = True
   created_at: datetime.datetime = time.time()
   enqueued_at: datetime.datetime = time.time()

   def asdict(self):
       return {** self.__dict__, "class": "SomeWorker"}
 

Моя проблема в том, что я не могу определить «class» как атрибут PusherNotificationJob, потому что это зарезервированное слово. Итак, мне нужно определить метод asdict для сериализации как dict и добавить атрибут «class», который я добавил здесь.

Есть лучший способ сделать это?

Комментарии:

1. Возможно, вы можете попробовать использовать для этого библиотеку. Взгляните на serpy. twilio.com/blog/2017/08 /…

Ответ №1:

Несколько вещей, на которые следует обратить внимание перед ответом: created_at и enqueued_at будут иметь одно и то же значение до тех пор, пока выполняется ваш код… если вы хотите, чтобы время было при создании экземпляра, используйте:

created_at: datetime.datetime = field(default_factory=time.time)

двигаемся дальше:

Вы можете переопределить __iter__ использование dict(instance) . Это было бы что-то вроде приведенного ниже, если у вас есть атрибут с именем class_: str = 'SomeWorker'

 def __iter__(self):
    for key in self.__dict__:
        if key == 'class_':
            key = 'class'
        yield key, self.__dict__
 

Если вам нужно __iter__ вести себя нормально, вы используете следующее:

 def convert_keys(self):
    for key in self.__dict__:
        value = self.__dict__[key]
        if key == 'class_':
            key = 'class'
        yield key, value 

def asdict(self):
    return {key: value for key, value in self.convert_keys()}