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

Python中父类动态默认参数与super.__init__的行为机制疑问

Python默认参数绑定机制导致的行为差异

问题场景

在Python 3.8/3.9中定义如下父类,试图在实例化时动态设置date属性:

from datetime import datetime, timezone
import time

class Parent():
    def __init__(self, date=datetime.now(timezone.utc).timestamp()):
        self.date = date

    def date_id(self):
        return id(self.date)

子类实例化代码如下(注:此处子类的__int__为笔误,应为__init__):

class Child(Parent):
    def __init__(self):
        super().__init__()

for i in range(10):
    time.sleep(1)
    print(Child().date_id())

运行后发现,连续10次实例化Child,self.date的id完全相同,和预期中每次实例化生成新值的行为不符。

修改父类,将动态赋值移到__init__方法体内后,即可实现预期行为:

class Parent():
    def __init__(self):
        self.date = datetime.now(timezone.utc).timestamp()

原因解析

这是Python的默认参数绑定机制导致的:

  • Python中,函数(包括类的__init__方法)的默认参数值,是在函数定义阶段就计算并绑定的,而非每次调用函数时重新计算。
  • 最初的Parent类中,date=datetime.now(timezone.utc).timestamp()这个默认参数,在Parent类被定义的那一刻就执行了一次,得到一个固定的时间戳数值,之后所有不传date参数的__init__调用,都会复用这个预先计算好的固定值。
  • 因为每次实例化都使用同一个数值,所以self.date指向的是同一个对象(Python对小数值存在对象复用优化,但核心原因还是默认参数仅计算一次),因此id()返回的结果完全相同。
  • 而将赋值逻辑移到__init__方法体内后,每次实例化调用__init__时,都会重新执行datetime.now(timezone.utc).timestamp()生成新的时间戳,自然会得到不同的对象引用,id()结果也就不同了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 07:00:04