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

如何在Python同一数据容器中定义可变、不可变及默认属性?

如何在Python同一数据容器中定义可变、不可变及默认属性?

当然可以实现!针对你提到的Pages类场景——需要first_page是带默认值的不可变属性、current_page是初始化后可变的属性、last_page是初始化后不可变的属性——我们可以通过Python dataclass的特性结合封装技巧来满足需求,下面给你两种实用的方案:

方案一:使用@property实现只读属性

这种方法通过“内部属性+只读属性暴露”的方式,把需要不可变的属性封装起来,只对外提供读取接口,符合Python的封装习惯:

from dataclasses import dataclass

@dataclass(slots=True)
class Pages:
    # 用下划线开头标记为内部属性,不建议外部直接访问
    _first_page: int = 0
    current_page: int
    _last_page: int

    # 暴露只读的first_page属性
    @property
    def first_page(self) -> int:
        return self._first_page

    # 暴露只读的last_page属性
    @property
    def last_page(self) -> int:
        return self._last_page

使用时的效果:

page = Pages(current_page=2, last_page=10)
print(page.first_page)  # 输出 0,正常读取
print(page.last_page)   # 输出 10,正常读取
page.current_page = 3   # 可以正常修改可变属性

# 尝试修改不可变属性会报错
page.first_page = 1  # AttributeError: can't set attribute
page.last_page = 11  # AttributeError: can't set attribute

方案二:重写__setattr__方法限制属性修改

如果你不想修改属性名称,可以通过重写__setattr__方法,直接拦截对不可变属性的修改操作:

from dataclasses import dataclass

@dataclass(slots=True)
class Pages:
    first_page: int = 0
    current_page: int
    last_page: int

    def __setattr__(self, name: str, value):
        # 规则:如果是first_page或last_page,且已经初始化过(对象已有该属性),则禁止修改
        if name in ('first_page', 'last_page') and hasattr(self, name):
            raise AttributeError(f"无法修改不可变属性 '{name}'")
        # 其他属性正常允许修改
        super().__setattr__(name, value)

使用时的效果:

page = Pages(current_page=2, last_page=10)
page.current_page = 3  # 正常修改
page.first_page = 1    # 抛出 AttributeError: 无法修改不可变属性 'first_page'

补充:其他数据容器的思路

如果你考虑用其他数据容器,也可以参考这些方向:

  • 字典(dict):自定义一个字典子类,重写__setitem__方法,限制特定键的修改;
  • 元组(tuple):元组本身是不可变的,无法满足既有可变又有不可变属性的需求,不适用;
  • Enum:枚举类的成员默认是不可变的,也不适合需要可变属性的场景。

总体来说,dataclass结合上述两种方案是最贴合你需求的实现方式,推荐根据你的代码风格选择合适的方案。

备注:内容来源于stack exchange,提问作者Abdulrahman Sheikho

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.21 11:28:06