Python类初始化中调用setter处理私有属性的疑问
如何在Python类初始化时复用setter的校验逻辑?
我想在类的初始化过程中,借助setter里定义的参数校验逻辑来创建私有属性,避免在__init__和setter中重复编写校验代码。
第一种可行但存在冗余的写法
这种写法在__init__和setter中重复了校验逻辑:
class Example(): def __init__(self, length: int): if length >= 0: self.__length = length else: self.__length = 0 @property def length(self): return self.__length @length.setter def length(self, length: int): if length >= 0: self.__length = length else: self.__length = 0 if __name__ == "__main__": test = Example(43) print(test.length) test = Example(-10) print(test.length)
第二种复用setter的写法(存在疑惑)
参考资料后,我尝试在__init__中调用setter来复用校验逻辑,代码可以运行,但存在疑问:
class Example(): def __init__(self, length: int): self.__length = length self.length = length @property def length(self): return self.__length @length.setter def length(self, length: int): if length >= 0: self.__length = length else: self.__length = 0
看起来这里有私有属性__length和“公有属性”length,但Python可视化工具只显示一个私有属性,请问该写法是否正确?有没有创建两个同名属性?
解答
不存在两个同名属性
length不是实例属性,而是通过@property装饰器创建的访问器(getter/setter的组合),它本质是对方法的封装,不会在实例上创建额外属性。实例中真正存储数值的只有__length这一个私有属性。原写法的冗余点
__init__里的self.__length = length是多余的:下一行self.length = length会调用setter方法,执行校验逻辑后覆盖__length的值。完全可以删掉这行冗余代码,直接调用setter完成初始化:class Example(): def __init__(self, length: int): self.length = length # 直接调用setter,复用校验逻辑 @property def length(self): return self.__length @length.setter def length(self, length: int): if length >= 0: self.__length = length else: self.__length = 0写法正确性
修正后的写法完全正确,既复用了setter的校验逻辑避免冗余,又保证了初始化时的参数合法性,实例中也只会存在__length这一个存储用的私有属性。
内容的提问来源于stack exchange,提问作者animeavatar420
相关产品推荐
相关产品推荐

