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

无对应属性的Python Property装饰器问题:无法设置number属性

问题:如何为Python类的number属性添加setter方法?

原Python类代码如下(仅定义了property的getter,无对应setter):

class Example(object):
    def __init__(self, csv_dict):
        self._csv_dict = csv_dict

    @property
    def name(self):
        return self["name"]

    @property
    def number(self):
        try:
            return round(float(self["number"]), 2)
        except ValueError:
            return None

    def __getitem__(self, field_name):
        value = self._csv_dict.get(field_name)
        if value:
            value = value.strip()
        return value

尝试修改number属性时遇到问题,两种尝试方式及错误如下:

第一种尝试写法:

example.number.setter(5)

错误:

AttributeError: 'float' object has no attribute 'setter'

第二种尝试写法:

@number.setter
def number(self, new_number):
   self._number = new_number
   # 也试过self.number = new_number

example.number = 5

错误:

AttributeError: can't set attribute

解决方案

问题根源:

  1. 第一种写法逻辑错误:example.number返回的是属性的具体值(float或None),并非property对象,所以不存在setter方法。
  2. 第二种写法的setter逻辑不匹配原类设计:原类的number属性值是从_csv_dict中读取的,而非存在独立的_number变量里,且直接赋值self.number = new_number会触发递归调用。

正确做法是给number属性添加对应setter,直接修改_csv_dict中的"number"键值,同时保持数据格式一致性:

class Example(object):
    def __init__(self, csv_dict):
        self._csv_dict = csv_dict

    @property
    def name(self):
        return self["name"]

    @property
    def number(self):
        try:
            return round(float(self["number"]), 2)
        except ValueError:
            return None

    # 添加正确的number setter方法
    @number.setter
    def number(self, new_number):
        # 将数值转为字符串存入_csv_dict,匹配原数据存储格式
        self._csv_dict["number"] = str(new_number)

    def __getitem__(self, field_name):
        value = self._csv_dict.get(field_name)
        if value:
            value = value.strip()
        return value

现在可正常修改number属性:

# 示例用法
csv_data = {"name": "test", "number": "123.456"}
example = Example(csv_data)
print(example.number)  # 输出 123.46

example.number = 789.123
print(example.number)  # 输出 789.12
print(example._csv_dict["number"])  # 输出 "789.123"

如果需要做数值合法性校验,可在setter中添加判断:

@number.setter
def number(self, new_number):
    if not isinstance(new_number, (int, float)):
        raise ValueError("number必须是整数或浮点数")
    self._csv_dict["number"] = str(new_number)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 12:03:27