我正在增强一个现有的类,它在__init__
函数中进行一些计算以确定实例状态。为了重用这些计算,从__getstate__()
调用__init__()
可以吗?
总结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
这样你就会注意到。
注意:使用"_"作为共享方法的前缀是任意的,您不必这样做。
通常更可取的做法是编写一个名为__getnewargs__
的方法。这样,Pickling机制将自动为您调用__init__
。
另一种方法是在子类中自定义构造函数类__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所建议的,这是棘手的&如果您在同一个类中调用它,您将进入困难的调试情况