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

Python中类内部变量的不同声明方式及最优方案选择

Python类静态常量三种实现的差异与选型

功能差异

三种实现的核心区别可以从所属作用域、访问逻辑、可修改性三个维度区分:

  • 第一种(类属性):属性属于类本身,所有实例共享,类和实例均可直接访问,默认允许修改
  • 第二种(普通property):属性属于实例级别的动态计算属性,每次访问都会重新执行返回逻辑,仅实例可访问,默认只读无法修改
  • 第三种(cached_property):属性属于实例级别的缓存属性,仅第一次访问时执行返回逻辑,结果会存入实例属性缓存,后续访问直接取缓存值,仅实例可访问,缓存生成后允许修改

各自优缺点

1. 类属性实现

class ApplePie:
    type = "apple"
    def __init__(self):
        print(f"I'm an {ApplePie.type} pie!")
  • 优点:实现最简单,内存占用最低,类和实例都可直接访问,修改类属性即可全局生效,不需要额外导入依赖
  • 缺点:没有只读保护,容易被意外修改(无论是类层面修改ApplePie.type还是实例层面赋值self.type都会覆盖原有值),不支持动态计算返回值

2. 普通property实现

class ApplePie:
    @property
    def type(self) -> str:
        return "apple"
    def __init__(self):
        print(f"I'm an {self.type} pie!")
  • 优点:天然只读,不会被意外修改,支持在返回逻辑里加动态计算规则,适合需要实时生成返回值的场景
  • 缺点:每次访问都会执行一次方法,有微小的性能开销(逻辑复杂时开销会放大),仅支持实例访问,类无法直接调用该属性

3. cached_property实现

from functools import cached_property
class ApplePie:
    @cached_property
    def type(self) -> str:
        return "apple"
    def __init__(self):
        print(f"I'm an {self.type} pie!")
  • 优点:仅第一次访问时执行返回逻辑,后续访问直接取缓存,性能优于普通property,也支持首次生成时加复杂计算逻辑
  • 缺点:需要额外导入依赖,缓存生成后可以被实例修改,也不支持类直接访问,若返回值需要动态更新则不适用

其他可选的更优实现

根据场景还有三种更常用的实现方案:

  1. 带Final标注的类属性
from typing import Final
class ApplePie:
    type: Final[str] = "apple"
    def __init__(self):
        print(f"I'm an {ApplePie.type} pie!")

在原有类属性的基础上加Final类型标注,静态检查阶段就会禁止修改该属性,既能保留类属性的所有优点,又能避免被意外修改,适合纯常量场景。
2. 枚举类实现

from enum import Enum
class PieType(Enum):
    APPLE = "apple"
class ApplePie:
    def __init__(self):
        print(f"I'm an {PieType.APPLE.value} pie!")

如果存在多个固定的类型常量,用枚举类实现规范性更强,完全避免硬编码,也天然不允许修改,适合多常量枚举的场景。
3. 类级别property(Python 3.9+支持)

class ApplePie:
    @classmethod
    @property
    def type(cls) -> str:
        return "apple"
    def __init__(self):
        print(f"I'm an {cls.type} pie!")

实现类级别的只读属性,类和实例都可以访问,同时保留只读特性,适合需要类层面访问动态属性的场景。

日常开发选型逻辑

我会根据场景灵活选择:

  • 纯固定常量场景:优先选带Final标注的类属性,实现最简单、性能最高,还有静态检查防修改的能力,90%的常规场景都适用
  • 需要动态计算、且值每次访问都要更新的场景:选普通@property
  • 需要动态计算、且值生成后不会变化的场景:选cached_property降低性能开销
  • 多固定常量的场景:选枚举类,避免硬编码错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 02:24:03