【问题标题】:How can I get a subclass to return a copy of itself, rather than the parent class it is inheriting from?如何让子类返回其自身的副本,而不是它继承的父类?
【发布时间】:2017-02-22 10:37:55
【问题描述】:

我定义了一个继承自另一个类的子类NewDataStructure。作用于对象本身的方法适用于这个子类。但是,创建副本的方法返回父类的对象,而不是子类。当我在其他方法中调用该方法时,这会导致很多问题。

有没有办法明确指示父类的命名方法应该返回子类的对象?

有没有办法指示所有继承的方法都应该返回子类的对象,而不是父类?

也许我可以将返回的对象传递给我班级的__init__ 函数?我需要相应地修改我的__init__... Pythonic 方式是什么?

import pandas as pd


class NewDataStructure(pd.DataFrame):
    def __init__(self, data, index, title):
        super(NewDataStructure, self).__init__(data=data, index=index)
        self.title = title


new_data_variable = NewDataStructure(data=None, index=None, title="")

changed = new_data_variable.unstack()

new_data_variable.reset_index(inplace=True)
unchanged = new_data_variable

print type(changed)
print type(unchanged)

<class 'pandas.core.series.Series'> 
<class '__main__.NewDataStructure'>

【问题讨论】:

    标签: python inheritance copy-constructor


    【解决方案1】:

    恐怕我认为你的问题是一个经典的XY question,你在问如何做你认为是 X 的解决方案的 Y,而实际上它不是 X 的一个很好的解决方案,可能更好的方法是尝试 X 的另一种解决方案。

    X 大致是“我如何将额外的功能绑定到DataFrame?”,正如@ppkt 指出的,这在this question 中进行了讨论。提到的子类化的主要问题是您遇到的问题,即该类具有生成该类的新实例的工厂方法,但这通常不是您可以从子类轻松操作的东西。

    不过,DataFrame 类通过_constructor 属性提供了一个解决方案(截至 2019 年 6 月正式发布,请参见 documentation):

    class DataFrame(NDFrame):
        ...
        @property
        def _constructor(self):
            return DataFrame
    

    可用于创建实例而不仅仅是DataFrame。因此,您可以通过覆盖子类上的该属性来解决您的问题:

    class NewDataStructure(pd.DataFrame):
        ...
        @property
        def _constructor(self):
            return NewDataStructure
    

    这是一种普遍认可的模式,将实例创建推迟到可由用户修改的工厂/构造方法。类似于 logging 模块使用logging.setLoggerClass() 设置记录器类的能力。

    【讨论】:

    • 本文描述的解决方案现在是documented and supported behaviour
    • 虽然在从DataFrame 继承的特定情况下这是一个很好的答案,但它不能回答一般问题。
    【解决方案2】:

    我认为这里描述了同样的问题:Pandas DataFrame Object Inheritance or Object Use?

    作为解决方案,您应该为 Pandas DataFrame 创建一个包装类。

    【讨论】:

      【解决方案3】:

      !!!我在使用小型智能手机!!!

      在您使用代码的方式中,您正在实现对函数的递归调用。

      据我所知,您创建了 new_variable_data 对象是正确的,但是您没有正确设计您正在调用的函数,除非它们是 pandas 的一部分,如果是这种情况,您将不得不创建一个 for每次 pd 并重新分配。

      至于作为参数传递的数据没有传递,您也需要合并一个 if 语句,然后将数据作为对象分配给 self。

      我认为你可以做你想做的事,你只需要重新定义类并考虑对象设计。

      我正在回家的路上,我会在我的笔记本电脑上为你编辑这个,并给你一个例子 .

      【讨论】:

        猜你喜欢
        • 2019-12-28
        • 2012-10-18
        • 1970-01-01
        • 1970-01-01
        • 2015-11-17
        • 2015-05-22
        • 1970-01-01
        • 2013-08-08
        • 2021-07-19
        相关资源
        最近更新 更多