【Python】解决类中特性(property)覆盖同名属性(attribute)报错问题
创始人
2024-03-16 06:08:28
0

一、问题描述

在设计一类加法的数据结构中,定义 Foo 对象可以拥有自己的取值 value 以及一系列可以通过累加得到该 Foo 对象的取值 value 的加法因子 factors

为简化对 Foo 对象的维护,希望每次获取 Foo 的取值 value 时,可以直接通过其加法因子列表元素的累加来获取其 value,而不需要每次手动对其 value 进行更新,因此考虑通过装饰器 @property 来实现该功能,如以下代码所示。

class Foo:def __init__(self, value, factors=None):self.value = valueself.factors = [self] if factors is None else factors@propertydef value(self):return sum([factor.value for factor in self.factors]) if len(self.factors) > 1 else self.valuefoo1 = Foo(value=3)
foo2 = Foo(value=5)
foo = Foo(value=8, factors=[foo1, foo2])print(f"The value of foo1 is: {foo1.value}.")
print(f"The value of foo2 is: {foo2.value}.")
print(f"The value of foo  is: {foo.value}.")

然而,运行该段代码后,程序报错 AttributeError,详细报错信息如下:

Traceback (most recent call last):File "attribute_property.py", line 11, in foo1 = Foo(value=3)File "attribute_property.py", line 3, in __init__self.value = value
AttributeError: can't set attribute

二、问题分析

出现该报错的原因是因为 property 装饰器作为特性重写了 value 属性,因此当创建新的 Foo 对象时,line 3 实际上将找到 @property 重写的 value 方法,而由于 @property 实际上只实现了 @getter 功能,因此可认为它只实现了可读属性的功能,而并没有实现 @setter 的功能。简单来说,这个时候是不能为它赋值的。(关于 @getter@setter 等相关装饰器内容请参见相关博客。)

三、解决方案

从上例中可以看到,此时我们是无法使用特性(property)直接覆盖同名属性(attribute)的。

一个简单的解决方案是将原来的 value 属性设置为保护变量,即在其变量名前添加下划线成为 _value。对应地,将 @property 实现的类方法中所返回的 value 属性更改为 _value。既然此时这二者都不同名了,自然也不会出现设置属性报错的问题了。

修改后的代码及运行结果如下所示:

class Foo:def __init__(self, value, factors=None):self._value = valueself.factors = [self] if factors is None else factors@propertydef value(self):return sum([factor.value for factor in self.factors]) if len(self.factors) > 1 else self._valuefoo1 = Foo(value=3)
foo2 = Foo(value=5)
foo = Foo(value=8, factors=[foo1, foo2])print(f"The value of foo1 is: {foo1.value}.")
print(f"The value of foo2 is: {foo2.value}.")
print(f"The value of foo  is: {foo.value}.")
---------------------------------------------
The value of foo1 is: 3.
The value of foo2 is: 5.
The value of foo  is: 8.

相关内容

热门资讯

佳发教育涨2.05%,成交额4... 7月8日,佳发教育盘中上涨2.05%,截至13:15,报11.44元/股,成交4645.13万元,换...
平安电工2025年7月8日涨停... 2025年7月8日,平安电工(sz001359)触及涨停,涨停价40.41元,涨幅9.99%,总市值...
8人被刑拘!甘肃天水通报幼儿血... 央视新闻客户端、人民日报客户端7月8日,甘肃天水市联合调查组发布关于天水市麦积区培心幼儿园幼儿血铅异...
互联网创业真的容易吗?我看未必... 互联网创业真的容易吗?我看未必分类:创业故事|Word文档下载互联网创业真的容易吗?我看未必我们一直...
创业公司 创业公司 创业公司值... 时不时冒出创业的冲动,想去做个屌爆的产品?创业公司忽悠你加入,说的是天花乱坠,到底真靠谱假靠谱?身边...
初中道德与法治评论题答题格式是... 初中道德与法治评论题答题格式是什么?“从不同的角度对上述材料进行分析评论”这种题应该怎么答?要写“答...
创业货款 创业货款 创业者 有的时候,如果我们想要贷款的话,大部分的人都会选择一个比较适合自己的,如果是创业贷款必须要满足一定的...
旭光电子股价跌5.02%,华夏... 7月8日,旭光电子跌5.02%,截至发稿,报12.68元/股,成交5.87亿元,换手率5.45%,总...
八戒包子加盟费多少,小本投资即... 对于包子类的早点小吃来说自然是现在更不错的选择,现在市面上有很多的特色餐饮小吃,尤其是对于包子类的品...
味丰源包子 总投资11 08万... 味丰源包子是深受顾客酷爱美食,传承自正宗的特征包子加盟,却又拥有了专归于自己的特征,在包子加盟市场显...