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

Python类中实现常量UUID Token:@property失效及私有属性疑问

问题解答

1. 实现常量UUID Token的@property方案

你在代码1里遇到的问题是:@property装饰的token属性每次调用都会执行uuid4().hex,所以每次返回全新的UUID。要实现无需传入参数、且Token保持常量的效果,有两种可靠方案:

方案一:初始化时生成Token(立即初始化)

像你写的代码2一样,在__init__方法里提前生成UUID并存在实例属性中,@property的getter只负责返回这个预先生成的值:

from uuid import uuid4

class Tokenizer:
    def __init__(self):
        self.__token = uuid4().hex  # 初始化时一次性生成
    
    @property
    def token(self):
        return self.__token  # 每次调用直接返回已有值

t = Tokenizer()
print(t.token)  # 两次输出相同
print(t.token)

方案二:懒加载生成Token(第一次调用时生成)

如果不想在实例初始化时就生成Token,而是等到第一次调用token属性时才生成,可以用懒加载的方式:

from uuid import uuid4

class Tokenizer:
    def __init__(self):
        self._token = None  # 用单下划线标记为“内部属性”
    
    @property
    def token(self):
        if self._token is None:
            self._token = uuid4().hex  # 第一次调用时生成
        return self._token

t = Tokenizer()
print(t.token)  # 第一次调用生成,后续调用返回同一值
print(t.token)

2. 修改__token不影响token属性的原因

这是Python的**名称修饰(Name Mangling)**机制导致的:

  • 当你在类内部定义self.__token时,Python会自动将这个属性重命名为_Tokenizer__token(格式为_类名__属性名),目的是避免子类意外覆盖父类的私有属性。
  • 当你尝试直接修改实例的__token(比如t.__token = "new_token"),实际上是给实例新增了一个普通的__token属性,而不是修改原来的_Tokenizer__token。
  • 因此@property装饰的token属性依然返回原来的_Tokenizer__token值,自然不受你新增的__token影响。

如果一定要修改这个属性(不推荐,双下划线属性本就是为了封装私有),需要使用修饰后的名称:

t = Tokenizer()
print(t.token)
t._Tokenizer__token = "modified_token"
print(t.token)  # 输出 modified_token

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 04:50:00