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

Python中检测到重复属性时如何触发DupError异常?

问题分析与解决方案

原代码问题

  1. 直接赋值私有属性绕过setter:原__init__里直接给self._attribute赋值,完全没触发@attribute.setter装饰的方法,setter里的重复值检查逻辑根本没运行,自然不会抛出DupError。
  2. 实例添加时机错误:Test.list_test.append(self)放在try-except块外部,不管属性值是否重复,都会把当前实例加入列表,这会导致后续检查出现错误的重复判定。

你觉得添加self.attribute = attribute是“绕开_attribute设计”其实是误解——_attribute作为私有属性(Python约定俗成的命名规范),本来就应该通过@property的setter方法来修改,直接操作_attribute才是违背了@property的封装意图。

正确修正方案

class DupError(Exception):
    pass

class Test:
    list_test = []

    def __init__(self, attribute):
        try:
            # 调用公开属性的setter,触发重复检查逻辑
            self.attribute = attribute
            # 仅当属性设置成功(无异常)时,才将实例加入列表
            Test.list_test.append(self)
        except DupError as e:
            msg = ' '.join(e.args)
            message = f'{e.__class__.__name__}: {msg}'
            print(message)

    @property
    def attribute(self):
        return self._attribute

    @attribute.setter
    def attribute(self, x):
        # 遍历已有实例,检查属性值是否重复
        for instance in Test.list_test:
            if instance.attribute == x:
                raise DupError('属性值重复!')
        # 检查通过后,给私有属性赋值
        self._attribute = x

t1 = Test('g')
t2 = Test('h')
# 此处会触发DupError并打印异常信息
t3 = Test('g')

修正关键点

  • 移除直接赋值self._attribute的操作,通过self.attribute = attribute触发setter的重复检查,符合@property的封装设计。
  • 将Test.list_test.append(self)移入try块内,确保只有合法的实例才会被加入列表,避免后续检查出错。
  • 优化setter里的遍历变量名,语义更清晰。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 13:25:17