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

Python中如何将类参数默认值设为带默认参数的其他类实例

问题原因

Python里函数(包括类的__init__方法)的默认参数是在函数定义阶段就被求值并固定下来的,而不是每次调用函数时重新生成。

在你的代码里,TestB.__init__的y = TestA()这个默认值,会在TestB类定义的时候就创建一个TestA实例,之后所有调用TestB()且不传y参数的情况,都会复用这个已经存在的TestA实例。所以你修改t.y.x后,后续创建的s.y其实是同一个对象,自然会看到x=7。

而直接调用TestA()时,每次调用都是在运行时创建新的实例,所以每次都能得到默认的x=2。

正确实现方式

有两种常用的解决方法:

方法一:用None作为默认标记

将默认值设为None,在__init__内部判断并创建新实例:

class TestA:
    def __init__(self, x=2):
        self.x = x
        
class TestB:
    def __init__(self, y=None):
        if y is None:
            y = TestA()
        self.y = y

这样每次调用TestB()不传参数时,都会在方法内部创建新的TestA实例,各个TestB对象的y属性互相独立。

方法二:用哨兵对象区分默认值和用户传入的None

如果需要允许用户主动传入None作为y的合法值,可以用一个唯一的哨兵对象做标记:

_sentinel = object()

class TestA:
    def __init__(self, x=2):
        self.x = x
        
class TestB:
    def __init__(self, y=_sentinel):
        if y is _sentinel:
            y = TestA()
        self.y = y

这种方式下,只有当用户完全不传入y参数时,才会创建新的TestA实例;如果用户传入None,则会直接使用None作为y的值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 06:20:48