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

如何正确继承并扩展pandas的Timestamp类?

解决继承pandas Timestamp类时实例类型不符的问题

问题背景

尝试继承pd.Timestamp添加自定义方法,代码如下:

class T(pd.Timestamp):
      
  def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)
  
  def to_unix_epoch(self) -> int:
    return int(self.to_pydatetime().timestamp())

t = T('2012-12-16')

但实例化后的t是pandas._libs.tslibs.timestamps.Timestamp实例,而非自定义类T的实例。尝试通过重写__new__并修改__class__属性解决,但不确定是否正确:

class T(pd.Timestamp):

    def __new__(cls, *args, **kwargs):
        instance = super().__new__(cls, *args, **kwargs)
        instance.__class__ = cls
        return instance

    def to_unix_epoch(self) -> int:
        return int(self.to_pydatetime().timestamp())

问题根源

pandas的Timestamp属于不可变类型,这类类型的实例创建完全由__new__方法控制,__init__只会在实例创建后执行。但pandas内部的Timestamp构造逻辑会忽略传入的自定义类cls,直接返回原生的pandas._libs.tslibs.timestamps.Timestamp实例,导致自定义类的__init__根本不会触发,实例类型自然不符。

可行解决方案

方案1:修正__new__实现(继承方式)

直接修改实例__class__的方式可以生效,但更稳妥的写法是先构造原生Timestamp,再替换类:

import pandas as pd

class T(pd.Timestamp):
    def __new__(cls, *args, **kwargs):
        # 先创建原生Timestamp实例
        ts_instance = pd.Timestamp(*args, **kwargs)
        # 将实例的类替换为自定义类
        ts_instance.__class__ = cls
        return ts_instance

    def to_unix_epoch(self) -> int:
        # 直接用Timestamp自带的timestamp()方法,无需转pydatetime
        return int(self.timestamp())

# 测试验证
t = T('2012-12-16')
print(type(t))  # 输出 <class '__main__.T'>
print(t.to_unix_epoch())  # 输出 1355606400

方案2:组合替代继承(更稳定)

由于Timestamp是不可变类型,继承后某些pandas内部操作(比如时间运算、类型转换)可能会把实例转回原生类型,导致自定义方法失效。此时用组合包装的方式更可靠:

import pandas as pd

class T:
    def __init__(self, *args, **kwargs):
        # 内部包装原生Timestamp实例
        self._ts = pd.Timestamp(*args, **kwargs)
    
    def to_unix_epoch(self) -> int:
        return int(self._ts.timestamp())
    
    # 代理原生Timestamp的所有属性和方法
    def __getattr__(self, attr_name):
        return getattr(self._ts, attr_name)

# 测试验证
t = T('2012-12-16')
print(type(t))  # 输出 <class '__main__.T'>
print(t.year)  # 输出 2012(原生Timestamp属性)
print(t.to_unix_epoch())  # 输出 1355606400

这种方式完全避免了继承不可变类型带来的兼容性问题,自定义方法能稳定生效,推荐在需要长期维护的代码中使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 20:00:16