如何正确继承并扩展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
相关产品推荐
相关产品推荐

