Python 在序列化之前修改对象

Python 在序列化之前修改对象,python,python-3.x,Python,Python 3.x,我有一个类C,它必须在父进程上使用GPU,但在子进程上只使用CPU 由于C是通过序列化发送给子进程的,为了更加安全,我决定将\uuuu reduce\uuuu添加到C中,以便在序列化之前修改一个标志: def __reduce__(self): """ This is just to avoid that we use the gpu on subprocesses. """ p = self.copy(shallow=True) p._cpu_only

我有一个类
C
,它必须在父进程上使用GPU,但在子进程上只使用CPU

由于
C
是通过序列化发送给子进程的,为了更加安全,我决定将
\uuuu reduce\uuuu
添加到
C
中,以便在序列化之前修改一个标志:

def __reduce__(self):
    """
    This is just to avoid that we use the gpu on subprocesses.
    """
    p = self.copy(shallow=True)
    p._cpu_only = True

    return _dummy_rebuild, (p,)
这不起作用,因为存在无限递归。我看到两种解决办法:

  • p
  • 返回
    p
    的属性并从中重建
  • 我认为选项1更可取,因为它不依赖于类的内部结构

    唯一的问题是我无法删除
    \uuuuuuuuuuuuuuuu
    。有什么办法吗?

    不可能(*)从
    p
    中删除
    \uuuuuuuuuuuuuuuuuuuuuuuuuuuu
    ,因为
    \uuuuuuuuuuuuuuuuuuuuuuuuuuuuu reduce>方法只存在于类中,而不存在于每个实例上。通过从类中删除它,可以从所有实例中删除它,但不能仅从选定实例中删除它

    (*从技术上讲,这取决于序列化程序。取决于序列化程序如何检查
    \uuuu reduce\uuu
    方法的存在,可能会或可能不会诱使它认为
    p
    没有。但这样做肯定不是一个好主意。)


    因此,您唯一/最好的选择是重写
    \uuuuuu reduce\uuuu
    方法,这样它就不会返回类的实例。

    不可能(*)从
    p
    中删除
    \uuuuuu reduce\uuuuuu
    ,因为
    \uuu reduce\uuu
    方法只存在于类中,而不存在于每个实例上。通过从类中删除它,可以从所有实例中删除它,但不能仅从选定实例中删除它

    (*从技术上讲,这取决于序列化程序。取决于序列化程序如何检查
    \uuuu reduce\uuu
    方法的存在,可能会或可能不会诱使它认为
    p
    没有。但这样做肯定不是一个好主意。)



    因此,您唯一/最好的选择是重写
    \uuuuuu reduce\uuuu
    方法,这样它就不会返回类的实例。

    …如果删除
    \uuuuu reduce\uuuu
    ,将如何序列化
    p
    ?您正在使用的序列化程序是否有可以处理
    C
    实例的默认机制?并不是说从实例中删除
    \uuuuu reduce\uuuu
    是可能的。@Aran Fey我的类已经可以序列化了。我添加了
    \uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu?您正在使用的序列化程序是否有可以处理
    C
    实例的默认机制?并不是说从实例中删除
    \uuuuu reduce\uuuu
    是可能的。@Aran Fey我的类已经可以序列化了。我添加了
    \uuuu reduce\uuuu
    就是为了这个目的。是否也无法向选定的实例添加方法?@Kiuhnm是的。这就像为实例的属性分配一个函数一样简单:
    instance.new\u method=some\u function
    (尽管该函数不会得到隐式的
    self
    参数)。如果您的方法需要
    self
    ,您可以执行
    instance.new\u method=some\u函数。\uu获取(实例)
    。此外,如果我手动添加
    \uu减少\uuuuuuu
    ,我可以删除它,因为它已添加到实例本身,对吗?@Kiuhnm是的。但是,只有当序列化程序直接在实例上检查
    \uuuuu reduce\uuuu
    的存在时,这才会产生效果,例如使用
    if hasattr(实例,'.\uuu reduce\uuu'):
    。如果它检查类,那就没用了。无论哪种情况,这都是丑陋的代码。是的,我同意。我会选择第二种。谢谢。是否也无法向所选实例添加方法?@Kiuhnm是的。这就像为实例的属性分配一个函数一样简单:
    instance.new\u method=some\u function
    (尽管该函数不会得到隐式的
    self
    参数)。如果您的方法需要
    self
    ,您可以执行
    instance.new\u method=some\u函数。\uu获取(实例)
    。此外,如果我手动添加
    \uu减少\uuuuuuu
    ,我可以删除它,因为它已添加到实例本身,对吗?@Kiuhnm是的。但是,只有当序列化程序直接在实例上检查
    \uuuuu reduce\uuuu
    的存在时,这才会产生效果,例如使用
    if hasattr(实例,'.\uuu reduce\uuu'):
    。如果它检查类,那就没用了。无论哪种情况,这都是丑陋的代码。是的,我同意。我会选择第二种。谢谢