首页 > 解决方案 > Python 继承,具有基类 init 始终调用的 set_up() 方法,同时在子类中具有不同的参数

问题描述

我想实现这样的目标。但是由于 Node 在没有参数的情况下调用 set_up,python 给出了缺少参数资源的错误。正确的方法是什么?基本上我想将一个类的初始化分解到 set_up 中,同时在提供必要的资源时让这个 set_up 方法可调用。子类需要 base 不需要的资源,同时 set_up 应始终由 init 调用,因为它执行实际初始化。

- - - - 编辑 - - - - -

我会尝试更好地解释我的动机。我想要一个 set_up 方法来初始化节点,这样我就可以在运行时重新初始化节点。我想通过 MyNode 中的这个 set_up 提供某些 Node 不需要的资源。所以理想的行为是

MyNode("node", resource="water").name == "node_altered"
MyNode("node", resource="water").resource == "water"
MyNode("node").set_up("water").resource == "water"
MyNode("node").set_up("water").set_up("fire") == "fire" 
MyNode("node").set_up("water").set_up().resource == "water"

这是我的尝试:

class Node:
    def __init__(self, name):
        self.name = name
        self.set_up()
        
    def set_up(self):
        self.name = name + "_altered"
    
class MyNode(Node):
    def __init__(self, name, resource=None):
        super().__init__(name)
        self.foo = None
        self.resource = resource
        
    def set_up(self, resource):
        super().set_up()
        self.foo = "foo"
        self.resource = resource
        return self
    
MyNode("foo").set_up(2).resource
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-70-01756d189150> in <module>
     17         return self
     18 
---> 19 MyNode("foo", "resource").set_up(2).resource

<ipython-input-70-01756d189150> in __init__(self, name, resource)
      9 class MyNode(Node):
     10     def __init__(self, name, resource):
---> 11         super().__init__(name)
     12         self.resource = None
     13 

<ipython-input-70-01756d189150> in __init__(self, name)
      2     def __init__(self, name):
      3         self.name = name
----> 4         self.set_up()
      5 
      6     def set_up(self):

TypeError: set_up() missing 1 required positional argument: 'resource'

标签: pythonoopinheritance

解决方案


为什么不定义一个默认NoneMyNode.set_up呢?

[...]
    [...]
        
    def set_up(self, resource=None):
        if resource is None:
            raise TypeError(
                "set_up() 'resource' argument cannot be None"
            )
            
        super().set_up()
        self.resource = resource
        return self


推荐阅读