python:在 __init__ 方法中过早调用 super().__init__ ?
我有一个类层次结构,其中 class Base
中的 __init__
执行一些预初始化,然后调用方法 calculate
。 calculate
方法在class Base
中定义,但预计会在派生类中重新定义。重新定义的 calculate
将使用一些仅在 class Derived
中可用的属性:
class Base:
def __init__(self, args):
# perform some pre-initialization
...
# now call method "calculate"
self.calculate()
class Derived(Base):
def __init__(self, args, additional_attr):
super().__init__(args)
# do some work and create new instance attributes
...
self.additional_attr = additional_attr
这不会起作用,因为 calculate
方法在 >class Derived
将在 self.additional_attr 分配之前被调用。
我无法将 super().__init__(args)
调用移至 __init__
方法的末尾,因为它所做的一些工作必须在处理 之前进行附加属性。
该怎么办?
I have a class hierarchy where __init__
in class Base
performs some pre-initialization and then calls method calculate
. The calculate
method is defined in class Base
, but it's expected to be redefined in derived classes. The redefined calculate
will use some of the attributes that are only available in class Derived
:
class Base:
def __init__(self, args):
# perform some pre-initialization
...
# now call method "calculate"
self.calculate()
class Derived(Base):
def __init__(self, args, additional_attr):
super().__init__(args)
# do some work and create new instance attributes
...
self.additional_attr = additional_attr
This is not going to work because calculate
method in class Derived
will be invoked before self.additional_attr is assigned.
I can't move super().__init__(args)
call to the end of the __init__
method because some of the work it does has to happen before processing additional_attr
.
What to do?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
也许您不应该在构造函数中调用
calculate()
。如果您无法通过允许基本构造函数首先完成来构造派生对象,那么恕我直言,您一定做错了什么。一个明智的方法是将该调用移出构造函数,并可能创建一个工厂方法来自动进行该调用。如果您需要预先计算的实例,请使用该方法。Perhaps you shouldn't have the
calculate()
call in your constructor then. If you can't construct a derived object by allowing the base constructor to complete first, then you must be doing something wrong IMHO. A sensible approach would be to move that call out of the constructor and perhaps create a factory method to make that call automatically. Then use that method if you need precalculated instances.恕我直言,这是一个糟糕的设计,而且你正在混淆 Python 的对象系统。考虑一下在其他面向对象语言(如 C++)中,您甚至无法控制基类的创建。派生类的构造函数在代码运行之前调用基构造函数。这种行为几乎总是表现良好的类层次结构所期望的,改变它只会导致问题。
当然,您可以进行一些修补(例如在调用
super
的构造函数之前分配self.additional_attr
或其他技巧),但更好的方法是更改您的设计,这样就不需要这样的黑客攻击。由于您在这里提供了一个抽象的示例,因此很难提供更全面的设计建议。This is bad design, IMHO, and you're obusing the object system of Python. Consider that in other OO languages like C++, you don't even have control over the creation of base classes. The derived class's constructor calls the base constructor before your code runs. Such behavior is almost always expected of well-behaved class hierarchies, and changing it can only lead to problems.
Sure, you can do some patching (such as assigning
self.additional_attr
before the call tosuper
's constructor, or other tricks), but the better way would be to change your design so that it won't require such hacks. Since you've presented an abstract example here, it's hard to give more comprehensive design advice.为了让这样的事情发挥作用,您需要设计一个协议,允许基类和派生类相互协作来完成对象初始化任务:
In order for something like this to work, you need to design a protocol that allows the base and derived class(es) to cooperate with each other to accomplish the object initialization task:
您可以将
additional_attr
作为参数传递给基类的__init__
方法,并将其从那里传播到calculate
方法吗?可以这样说:
这是一种迂回的方式,但由于没有关于预初始化步骤的信息,很难说上述方法是否对您有帮助。
Can you pass the
additional_attr
as a parameter to__init__
method of base class and propogate it from there tocalculate
method?Say something like:
This is roundabout way, but with no information about what the pre-initialisation steps are, it is hard to say whether the above approach would help you.