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

Python通用属性创建简化实现遇问题,求解决方案

解决Python自定义@property重复代码的问题

问题背景

作为Python新手,编写类时需要重复编写大量@property相关的getter、setter代码:

@property
def example(self):
    return self._example

@example.setter
def example(self, example):
     if # 校验条件:
          self._example = example

为了减少重复,编写了Util.custom_property工具方法自动生成属性的getter、setter和deleter,但遇到两个问题:

  • 实例化City对象时传入不符合条件的name(如"a")不会触发校验,只有修改属性时才报错
  • 希望在目标类内直接调用方法添加属性,但原实现无法直接将属性添加到目标类,类外调用又担心引用问题

问题1:实例化不触发校验的解决办法

原代码中__init__直接给私有属性self._name赋值,没有走setter方法,所以校验逻辑不会执行。解决办法是在__init__中通过公开属性赋值,触发setter的校验:

修改后的City类初始化方法:

def __init__(self, name):
    self.name = name  # 调用公开属性的setter,触发校验

这样实例化时传入非法值(如"a")会直接触发name_conds里的校验逻辑,抛出对应的异常。


问题2:在目标类内便捷添加属性的优化

原Util.custom_property返回getter/setter/deleter列表,需要手动创建property,不够便捷。可以优化工具方法,让它直接给目标类添加属性,或者使用类装饰器简化流程:

方案1:修改Util类,直接给目标类添加属性

修正原方法中deleter的错误(原代码删除的是self._value,应该对应私有属性_{prop}),并让方法接受目标类作为参数:

class Util:
    @classmethod
    def add_custom_property(cls, target_class, prop, conds=None, deletable=False):
        def getter(self):
            return getattr(self, f'_{prop}')

        def setter(self, value):
            if conds is None or conds(value):
                setattr(self, f'_{prop}', value)
            else:
                raise ValueError(f'Invalid value for {prop}')

        def deleter(self):
            if deletable:
                delattr(self, f'_{prop}')  # 修正为对应私有属性
            else:
                print(f"This attribute {prop} can't be deleted.")

        # 直接将property添加到目标类
        setattr(target_class, prop, property(getter, setter, deleter))

使用方式:

from utils import Util

def name_conds(name):
    if not isinstance(name, str):
        raise TypeError("City name must be a string")
    if not name.strip():
        raise ValueError("City name cannot be blank")
    if not 2 <= len(name) <= 25:
        raise ValueError("City name length must be between 2 and 25 characters")
    return True

class City:
    def __init__(self, name):
        self.name = name

# 直接给City类添加自定义属性
Util.add_custom_property(City, "name", name_conds)

方案2:使用类装饰器更优雅地添加属性

如果觉得类外调用不够直观,可以用类装饰器实现,在类定义时直接指定要添加的属性:

def add_custom_property(prop, conds=None, deletable=False):
    def decorator(cls):
        def getter(self):
            return getattr(self, f'_{prop}')

        def setter(self, value):
            if conds is None or conds(value):
                setattr(self, f'_{prop}', value)
            else:
                raise ValueError(f'Invalid value for {prop}')

        def deleter(self):
            if deletable:
                delattr(self, f'_{prop}')
            else:
                print(f"This attribute {prop} can't be deleted.")

        setattr(cls, prop, property(getter, setter, deleter))
        return cls
    return decorator

使用方式:

@add_custom_property("name", name_conds)
class City:
    def __init__(self, name):
        self.name = name

这种方式更符合Python的装饰器语法,代码结构更清晰。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 14:25:00