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
相关产品推荐
相关产品推荐

