You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现返回继承类的类方法,优化自定义数据拟合类的属性传递

解决方法:优雅实现子类继承父类属性的拟合类

首先,咱们先搞定你最初遇到的TypeError:你定义的fit方法没有包含self参数!当你用实例调用f.fit(3)时,Python会自动把实例f作为第一个参数传递给方法,但你的方法定义只接受lookback这一个参数,所以就会报“takes 1 positional argument but 2 were given”的错误。这是Python类方法的基础问题,所有实例方法都需要把self作为第一个参数。

接下来回到你核心的需求:让fitter_fit自动继承fitter的所有属性,不用手动逐个传递。这里有两种简洁的实现方式:

方式一:利用继承+关键字参数展开

让fitter_fit继承fitter,然后在fit方法里用**vars(self)把当前fitter实例的所有属性打包成关键字参数传递给子类,子类通过父类构造方法初始化这些属性:

import datetime as dt
import pandas as pd
from scipy.optimize import curve_fit
from dateutil import relativedelta
import numpy as np

def ex(x, a, b):
    """Exponential function"""
    return a * b**x

def p2y(idx):
    """Evaluate number of periods to a year"""
    return int(12/(relativedelta.relativedelta(idx[-1],idx[-2]).months))

class fitter:
    """Creates fit parameters over a lookback number of years"""
    def __init__(self, use_y, kind, true_y=None):
        self.use_y = use_y
        # 简化true_y的赋值逻辑
        self.true_y = true_y if true_y is not None else use_y
        self.kind = kind
        self.p = p2y(use_y.sort_index().index)
    
    def fit(self, lookback):
        # 用**vars(self)自动传递当前实例的所有属性
        return fitter_fit(lookback, **vars(self))

class fitter_fit(fitter):
    """Perform fit over lookback number of years"""
    def __init__(self, lookback, **kwargs):
        # 先调用父类构造方法,初始化继承的属性
        super().__init__(**kwargs)
        self.lookback = lookback
        # 执行拟合逻辑
        n = int(lookback * self.p)
        x = np.linspace(1, n, n)
        dates = self.use_y.index[-n:]
        y = self.use_y.values[-n:]
        if self.kind == 'exp':
            self.popt, self.pcov = curve_fit(ex, x, y)

# 测试代码
qtrly=pd.DataFrame(
    index=[dt.datetime(2020,1,1),dt.datetime(2020,4,1),dt.datetime(2020,7,1),dt.datetime(2020,10,1)],
    data={'fre':[0.55,0.6,0.62,0.7]}
)
f=fitter(qtrly.fre,'exp')
fit_result = f.fit(3)
# 查看拟合参数
print(fit_result.popt)
# 验证继承的属性
print(fit_result.true_y.equals(qtrly.fre))

方式二:直接复制父类实例的属性字典

如果你不想依赖继承的构造方法,也可以直接把父类实例的属性字典复制到子类实例中,这种方式更直接:

class fitter:
    """Creates fit parameters over a lookback number of years"""
    def __init__(self, use_y, kind, true_y=None):
        self.use_y = use_y
        self.true_y = true_y if true_y is not None else use_y
        self.kind = kind
        self.p = p2y(use_y.sort_index().index)
    
    def fit(self, lookback):
        # 传递当前实例给子类构造方法
        return fitter_fit(self, lookback)

class fitter_fit:
    """Perform fit over lookback number of years"""
    def __init__(self, parent_fitter, lookback):
        # 直接复制父类实例的所有属性
        self.__dict__.update(parent_fitter.__dict__)
        self.lookback = lookback
        # 执行拟合逻辑
        n = int(lookback * self.p)
        x = np.linspace(1, n, n)
        dates = self.use_y.index[-n:]
        y = self.use_y.values[-n:]
        if self.kind == 'exp':
            self.popt, self.pcov = curve_fit(ex, x, y)

为什么这两种方式更优雅?

  • 不用手动列出所有需要传递的属性,当你给fitter类新增属性时,子类会自动继承,不用修改fit方法或子类构造。
  • 代码更简洁,可读性更高,减少了重复代码。
  • 方式一保持了类的层次结构,符合面向对象的设计原则;方式二更灵活,适合不需要严格继承关系的场景。

内容的提问来源于stack exchange,提问作者OldKingCole

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 21:27:31