Python3, как сериализовать переменную класса в классе, используя __slots__ - PullRequest
0 голосов
/ 26 сентября 2018

У меня есть класс, который является интерфейсом поддержки, используемым между потоками.

В силу своей природы мне пришлось создать пользовательские __ getstate __ и __ setstate __ .У класса есть UniqueCounter, чтобы помочь создать уникальные идентификаторы для указанного интерфейса.Однако класс также использует ___ слотов __ для ограничения накладных расходов (многие могут быть созданы из указанного класса)

Класс выглядит следующим образом:

class WriterIf(object):

  UniqueCounter = 0

  __slots__ = [
    '_UpdateQueue',
    'WriterIfId',
    '_weakWriterPtr',
    '_MasterIf',
    '_TestName',
    '_TestCaseName',
    '_GroupeName',
    '_TestStatus',
    '_Serialized',
  ]

  def __init__(self, WriterMQ, MasterIf : bool = False):
    self._UpdateQueue         = WriterMQ
    self.WriterIfId           = self.UniqueCounter

    self._GroupeName          = None
    self._TestCaseName        = None
    self._TestName            = None
    self._TestStatus          = self.T_STATUS_NA
    self._Serialized          = False


    type(self).UniqueCounter += 1

    if MasterIf:
      self.WriterIfId = -1

    self._MasterIf = MasterIf


  # ---------------------------------------------------------------------------------------------------------------------
  def __getstate__(self):
    self.RmQueue()
    self._Serialized = True
    returnValue = {slot: getattr(self, slot) for slot in self.__slots__ if hasattr(self, slot)}
    return returnValue

  # ---------------------------------------------------------------------------------------------------------------------
  def __setstate__(self, stat):
    for slot, value in stat.items():
      setattr(self, slot, value)

Это работает так, как оноследует, сериализуя мои слоты и восстанавливая мои значения __ slots__.Однако мой UniqueCounter не обновляется, что имеет смысл, поскольку он не является частью ** ___ слотов __ .(На самом деле я не уверен, что мой UniqueCounter нарушает преимущество __ слотов __ ).

Теперь я попытался упаковать эту переменную в мое returnValue в __ getstate__ метод.Однако, если я пытаюсь установить его непосредственно на __ setstate __ , я получаю объект 'mappingproxy', не поддерживающий назначение элемента ошибка.Я не могу добавить его с помощью setattr, потому что атрибут только для чтения.

Есть идеи ?.Должен ли я прекратить использование слотов (я еще не пробовал, если это работает), но я хотел бы придерживаться ** __ slots__, если это возможно.

1 Ответ

0 голосов
/ 26 сентября 2018

Если я изменю два метода __ getstate __ и __ setstate __ , как показано ниже

  # ---------------------------------------------------------------------------------------------------------------------
  def __getstate__(self):
    self.RmQueue()
    self._Serialized = True
    returnValue = {slot: getattr(self, slot) for slot in self.__slots__ if hasattr(self, slot)}
    returnValue['ClassVariables'] = {'UniqueCounter': type(self).UniqueCounter}
    return returnValue

  # ---------------------------------------------------------------------------------------------------------------------
  def __setstate__(self, stat):
    for slot, value in stat.items():
      if slot == 'ClassVariables':
        for ClassVariableName, ClassValue in value.items():
          if ClassVariableName == 'UniqueCounter':
            self.SetUniqueCounter(ClassValue)
      else:
        setattr(self, slot, value)

и добавлю метод

  # -------------------------------------------------------------------------------------------------------------------------------------------------------------
  def SetUniqueCounter(self, val):
    type(self).UniqueCounter = val

, я делаюnot get error Объект 'mappingproxy' не поддерживает назначение элементов и теперь может устанавливать мой UniqueCounter.

Однако я не понимаю, почему это законно, а прямого назначения нет.Если бы кто-нибудь мог прояснить это для меня, я был бы рад.Однако вышеперечисленное работает, и я получаю набор переменных класса после сериализации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...