Python3如何使用__slots __

时间:2018-09-26 10:05:06

标签: python-3.x serialization multiprocessing

我有一个类,它是线程之间使用的支持接口。

由于其性质,我不得不创建一个自定义的 __ getstate __ __ setstate __ 。该类具有UniqueCounter,可帮助为所述接口创建唯一的ID。但是,该类还使用 __ slots __ 来限制开销(可以创建许多该类)

该类如下:

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无法更新,这很有意义,因为它不是** __ slots __ 的一部分。 (我确实不确定我的UniqueCounter是否会破坏 __ slots __ 的优势)。

现在,我尝试通过 __ getstate __ 方法将该变量打包到我的 returnValue 中。但是,如果尝试直接在 __ setstate __ 上进行设置,则会出现'mappingproxy'对象不支持项目分配错误。 我不能使用setattr添加它,因为该属性是只读的。

有什么想法吗?。我应该停止使用插槽吗(如果可行,我还没有尝试过),但如果可能的话,我想坚持使用** __ slots __。

1 个答案:

答案 0 :(得分:0)

如果我更改如下所示的两个方法 __ 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

我没有收到错误'mappingproxy'对象不支持项目分配,现在可以设置我的UniqueCounter。

但是我不明白为什么这是合法的,而直接转让却不是。如果有人能为我解决这个问题,我将很高兴。但是上面的工作,序列化后,我得到我的类变量设置。