【问题标题】:Is it OK to call __init__ from __setstate__从 __setstate__ 调用 __init__ 可以吗
【发布时间】:2014-06-21 02:32:31
【问题描述】:

我正在增强一个现有类,该类在__init__ 函数中进行一些计算以确定实例状态。可以从__getstate__() 调用__init__() 以重用这些计算吗?

【问题讨论】:

  • 如果课程是你的,当然!我建议将这些计算分成一个类方法并从__init____getstate_ 调用它
  • 我会支持@Kroltan - 我会将这些计算移到单独的实例/类方法中,而不是再次调用__init__
  • 我很困惑。你想从__setstate____getstate__ 拨打__init__ 吗?

标签: python pickle init getstate


【解决方案1】:

总结 Kroltan 和 jonsrharpe 的反应:

技术上没问题

从技术上讲,它会起作用,如果你做得好,它可以被认为是好的。

实际上这很棘手,避免这样做

如果您以后编辑代码并触摸__init__,那么很容易(甚至对您来说)忘记在__setstate__ 中使用,然后您进入难以调试的情况(问自己,它来自哪里)。

class Calculator():
    def __init__(self):
        # some calculation stuff here
    def __setstate__(self, state)
        self.__init__()

计算的东西最好隔离到另一个共享方法中:

class Calculator():
    def __init__(self):
        self._shared_calculation()   

    def __setstate__(self, state)
        self._shared_calculation()

    def _shared_calculation(self):
        #some calculation stuff here

这样你会注意到的。

注意:使用“_”作为共享方法的前缀是任意的,您不必这样做。

【讨论】:

  • 我觉得不调用 init 来构造对象更奇怪。
【解决方案2】:

另一种方法是在子类中自定义构造函数类__init__。理想情况下,最好有一个构造函数类并根据您在子类中的需要进行更改

class Person:
    def __init__(self, name, job=None, pay=0):
        self.name = name
        self.job = job
        self.pay = pay

class Manager(Person):
    def __init__(self, name, pay):                   
        Person.__init__(self, name, 'title', pay)  # Run constructor with 'title'

以这种方式调用构造函数类被证明是 Python 中非常常见的编码模式。就其本身而言,Python 使用继承在构造时仅查找和调用一个 __init__ 方法——类树中最低的一个。

如果您需要在构造时运行更高的__init__ 方法,则必须手动调用它们,通常通过超类名称调用,如上面的代码所示。他的方式是你增加超类构造函数并根据你的喜好完全替换子类中的逻辑

正如 Jan 所建议的那样,这很棘手,如果您在同一个类中调用它,您将进入困难的调试情况

【讨论】:

  • 这没有回答关于__setstate__ 调用__init__ 的原始问题。
【解决方案3】:

通常最好编写一个名为__getnewargs__ 的方法。这样,Pickling 机制会自动为您调用__init__

【讨论】:

  • 没能成功。阅读文档,仍然。采用上述方法
猜你喜欢
  • 2010-11-26
  • 2011-04-03
  • 2020-09-03
  • 2016-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-30
相关资源
最近更新 更多