PAYATHON 2026

Python 如何在实例化类时根据另一个属性校验当前属性?

数据小陈

可以。在 setter 中用 self.planet_lifetime 访问另一个实例属性,并在给 species_lifetime 赋值前先初始化 planet_lifetime。

为什么初始化时会报错?

执行下面这行代码时,Python 会立即调用 species_lifetime 的 setter:

self.species_lifetime = species_lifetime

如果 setter 读取 self.planet_lifetime 时,构造函数还没有执行下一行赋值,就会触发 AttributeError。

示例代码与描述中的报错还有一个区别:如果按示例原样写成 if value > planet_lifetime:,在没有同名全局变量等外部定义的情况下,通常会触发 NameError。__init__ 的参数是该方法的局部变量,另一个方法不能直接访问。

如何修改代码?

先设置被依赖的属性,再设置需要校验的属性:

class Planet:
    def __init__(self, species_lifetime, planet_lifetime):
        self.planet_lifetime = planet_lifetime
        self.species_lifetime = species_lifetime

    @property
    def species_lifetime(self):
        return self._species_lifetime

    @species_lifetime.setter
    def species_lifetime(self, value):
        if value > self.planet_lifetime:
            raise ValueError(
                "Species lifetime can't be longer than planet lifetime"
            )
        self._species_lifetime = value

这样调用 setter 时,self.planet_lifetime 已经存在。构造函数的参数顺序可以保持不变,只需调整内部赋值顺序。

使用示例:

planet = Planet(species_lifetime=80, planet_lifetime=100)
print(planet.species_lifetime)  # 80

planet.species_lifetime = 90   # 允许
planet.species_lifetime = 120  # 抛出 ValueError

把名称改成 self._planet_lifetime 不会自动创建属性,仍然要先赋值才能读取。_planet_lifetime 不带 self. 时,也不是在访问实例属性。

后续修改另一个属性时怎么办?

上面的实现会在每次设置 species_lifetime 时校验,但直接修改 planet_lifetime 不会触发这个 setter。例如:

planet = Planet(80, 100)
planet.planet_lifetime = 50

此时两个属性不再满足约束。如果要求对象始终满足 species_lifetime <= planet_lifetime,还需要在 planet_lifetime 的 setter 中校验,或提供统一更新两个属性的方法,在赋值前检查整组新值。

示例假定两个值能够使用 > 比较。类型、负数或空值等限制,需要根据业务规则另行添加。

备注:内容仅供参考。