从__setstate__调用__init__可以吗

时间:2014-05-04 20:57:31

标签: python pickle init getstate

我正在增强现有的类,它在__init__函数中进行一些计算以确定实例状态。是否可以从__init__()致电__getstate__()以重复使用这些计算?

3 个答案:

答案 0 :(得分:2)

总结来自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

这样你就会注意到。

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

答案 1 :(得分:2)

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

答案 2 :(得分:-1)

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

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所建议的那样,它很棘手。如果你在同一个类中调用它,你将进入困难的调试情况