【问题标题】:Is it possible to update an object initialized in a superclass from a subclass?是否可以从子类更新在超类中初始化的对象?
【发布时间】:2013-07-21 10:25:55
【问题描述】:

假设我有一堂课:

class SuperClass():
    def __init__(self, number):
       self._inputnumber = number
       self._initallist = []

然后我想构建此类的子类,这些子类具有可以将项目添加到初始化列表、从中读取项目或从中删除项目的方法。例如。

class SubClass(SuperClass):
     def __init__(self, number, current_line, new_line): 
        self._number = number
        self._thisline = current_line
        self._gohere = new_line
     def execute(self):
        (SuperClass._initallist).append(self._thisline + 1)

这是我正在尝试做的一个粗略的例子。我希望能够为几个类提供我的初始列表,以便他们都可以按照上面所示的方式对其进行操作。但是,在我的情况下最终发生的事情是我收到一个 AttributeError 说我的 SuperClass 没有命名属性。

AttributeError: type object 'SuperClass' has no attribute '_initiallist'

关于如何做到这一点的任何提示?甚至有可能还是我必须做其他事情才能达到这个结果?

【问题讨论】:

    标签: python inheritance subclass superclass


    【解决方案1】:

    _initallist是实例属性,Super._initallist不能访问。

    我认为你想要做的是下面。您需要在SubClass 中初始化SuperClass。我认为如果这是一个正确的 is-one 关系,SubClass 中需要有一个number

    class SuperClass():
        def __init__(self, number):
           self._inputnumber = number
           self._initallist = []
    
    class SubClass(SuperClass):
         def __init__(self, number, current_line, new_line):
            SuperClass.__init__(self, number) 
            self._thisline = current_line
            self._gohere = new_line
         def execute(self):
            self._initallist.append(self._thisline + 1)
    

    【讨论】:

    • 这是正确的基本想法,但更好的选择是使用 Python 推荐的新样式类,通过编写 class SuperClass(object): 然后从 SubClass.__init__() 调用 super(SubClass,self).__init__(number)
    • 是的。内置的super 是更好的方法。
    • 你是对的,这是一个 is-one 关系,这几乎可以工作,但就像 RussW 所说,这给了我每个子类的新列表实例。因此,当我两次调用该方法并在最后为列表添加一个打印语句时,它给了我两个列表,每个列表都有一个数字,而不是第二次有两个项目。
    【解决方案2】:

    只要self._initiallist.append(self._thisline + 1)

    【讨论】:

    • 我也尝试过这样做。在这种情况下,我得到另一个 AttributeError 说我的子类没有属性 _initiallist。
    • 你是如何初始化超类/子类的?
    【解决方案3】:

    “我想构建这个类的子类,这些子类具有可以将项目添加到初始化列表的方法,...”

    您是说您希望子类继承 instance 属性 _initiallist 并提供对其采取行动的方法吗?如果是这种情况,则子类的 instances 将每个都有一个 _initiallist 属性但是每个类的每个实例的 _initiallist 将是一个不同的列表。

    在这种情况下,解决方案如zhangyangyu所述。


    “我希望能够为几个班级提供我的初始列表,以便他们都可以按照上面所示的方式对其进行操作。”

    根据标题,我可以将其解释为:我希望超类的某些 instance_initiallist 属性可用于几个 instances子类,以便它们都可以根据相同的确切列表进行操作。

    据我所知,如果_initiallist 是类属性,您可以这样做,或者您可以在实例化子类时将超类的实例作为__init__ 参数传递。

    另外,这意味着您示例中的两个类不具有 is a 关系,而是您的超类实际上是一个共享对象 (AFAIK)。

    如果您将其设为类属性,那么您将失去一些灵活性,因为超类的不同实例都将具有指向同一个确切列表的属性_initiallist。如果您将其保留为实例属性并将超类的实例作为参数(作为共享对象)传递给子类,那么您仍然可以实现您想要做的事情并且仍然可以灵活地创建多个实例您的共享对象。

    class SharedObject(object):
    
        def __init__(self, number):
            self._inputnumber = number
            self._initiallist = []
    
    
    class Client(object):
    
        def __init__(self, obj, current_line, new_line):
            self._sharedobj = obj
            self._thisline = current_line
            self._gohere = new_line
    
        def execute(self):
            self._sharedobj._initiallist.append(self._thisline + 1)
    

    【讨论】:

    • 在这种情况下,obj 到底是什么?是 SharedObject 类吗?
    • 这是SharedObject 类的一个实例。我实际上应该将它命名为sharedobj,就像属性一样。它是否完全捕捉到了你想要做的事情?
    • 它最终成功了,我意识到我并不真的需要继承,只需将 SharedObject 作为参数传递到我的执行语句中,然后执行就可以采取行动初始列表
    猜你喜欢
    • 2019-05-09
    • 2016-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-27
    • 1970-01-01
    相关资源
    最近更新 更多