Python使用__getattribute__拦截类方法调用触发递归错误怎么解决?
递归报错原因
- 核心原因:
__getattribute__会拦截所有对类实例属性的访问,你在方法内部直接写self.token_exp、self._get_token时,会再次触发__getattribute__逻辑,形成无限递归。 - 附加错误:原代码
__init__中初始化的过期字段是self.exp,但校验时调用的是不存在的self.token_exp,字段不匹配会触发异常导致返回空值。
修复后代码
import time import adlfs # 你原有updateTokenExpiration方法如果是外部实现保留即可,这里仅做示例定义 def updateTokenExpiration(token): return token.token.expires_on class FileSystem(adlfs.FileSystem): def __init__(self, *args, **kwargs): try: self.name, self.token = self._get_token() if self.name is not None: kwargs["name"] = self.name if self.token is not None: kwargs["token"] = self.token # 统一过期字段命名为token_exp self.token_exp = updateTokenExpiration(self.token) super().__init__(*args, **kwargs) except Exception as exception: print(exception) def _get_token(self) -> (str, 'Credential'): # 此处保留你原有获取token的业务逻辑即可 return name, token def __getattribute__(self, attr): # 优先通过父类方法获取属性,避免触发自我拦截 attribute = super().__getattribute__(attr) # 跳过私有方法、魔术方法,不需要做token校验 if attr.startswith('_') or not callable(attribute): return attribute curr_time = int(time.time()) # 内部读取属性全部走super调用,规避递归 token_exp = super().__getattribute__('token_exp') if curr_time > token_exp: def refresh_and_run(*args, **kwargs): _get_token = super().__getattribute__('_get_token') self.name, self.token = _get_token() self.token_exp = updateTokenExpiration(self.token) super().updateConnection() return attribute(*args, **kwargs) return refresh_and_run else: return attribute
关键修改说明
- 所有
__getattribute__内部的实例属性读取都通过super().__getattribute__执行,完全规避自我触发的递归问题 - 统一了过期时间字段命名,避免字段不存在的异常
- 增加了方法过滤逻辑,不对下划线开头的私有方法、魔术方法做拦截,减少不必要的逻辑开销
- 修复了闭包逻辑,确保刷新token后调用的是最新连接的方法实例
内容的提问来源于stack exchange,提问作者Manjur
相关产品推荐
相关产品推荐

