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
相关产品推荐
相关产品推荐

