您 可以
__init__通过
__new__直接致电 来
规避。然后,您可以创建给定类型的对象,并为调用替代方法
__init__。这是
pickle可以做到的。
但是,首先,我非常想强调一点,这是您 不应该
做的事情,无论您要达到什么目的,都有更好的方法可以做到,其中一些已在其他答案中提到。特别是,跳过call是一个 坏 主意
__init__。
创建对象时,或多或少会发生这种情况:
a = A.__new__(A, *args, **kwargs)a.__init__(*args, **kwargs)
您可以跳过第二步。
这就是为什么您 不应该这样
做的原因:的目的
__init__是初始化对象,填写所有字段并确保
__init__还调用父类的方法。有了
pickle它是一个例外,因为它尝试存储与该对象关联的所有数据(包括为该对象设置的
任何 字段/实例变量),因此,
__init__上次设置的任何内容都将由pickle还原,没有需要再次调用它。
如果跳过
__init__并使用替代的初始化程序,则会有某种形式的代码重复-
实例变量将在两个位置填充,并且很容易在其中一个初始化程序中错过其中一个,或者不小心使其中一个两个填充字段的行为不同。这样就可以发现难以跟踪的细微错误(您必须
知道 调用了哪个初始化程序),并且代码将更难以维护。更不用说如果您使用继承会陷入更大的混乱-
问题将在继承链中蔓延,因为您必须在链的各处使用此替代初始化器。
通过这样做,您或多或少会覆盖Python的实例创建并自行创建。Python已经为您很好地做到了这一点,无需重新发明它,它会使使用您的代码的人们感到困惑。
最好的替代
__init__方法是:对于将所有实例变量正确初始化的类的所有可能实例,请使用单个方法。对于不同的初始化模式,请使用以下两种方法之一:
__init__
通过使用可选参数,为处理您的案件提供不同的签名。- 创建几个用作替代构造函数的类方法。确保它们都按正常方式(即调用
__init__
)创建类的实例,如Roman Bodnarchuk所示,同时执行其他工作或执行其他 *** 作。最好将它们传递给类(并__init__
处理)所有数据,但是如果这不可能或不方便,则可以在创建实例并__init__
完成初始化之后设置一些实例变量。
如果
__init__具有可选步骤(例如,像处理该
data参数那样,尽管您必须更具体一些),则可以将其设为可选参数,也可以使之成为执行该处理的常规方法…或同时执行两者。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)