实例化相互依赖对象时如何避免重复登录?
解决方案:实现登录会话的复用与自动重登
核心思路
- 让
LogSess维护持久化的会话对象,避免每次调用都新建会话并重复登录 - 实现懒加载登录:仅在首次使用会话、会话过期或检测到需要登录的响应时执行登录
- 让所有数据请求类(
DataReq及同类)共享同一个LogSess实例,消除重复初始化的问题
重构后的代码实现
import requests from requests.exceptions import JSONDecodeError URL_LOGIN = "https://www/login..." URL_TDATA = "https://www/services-..." class LogSess: def __init__(self, username="foo", password="bar"): self.username = username self.password = password self._session = None # 保存持久化会话,初始为None def _login(self): """执行登录操作,更新会话""" self._session = requests.Session() login_response = self._session.post(URL_LOGIN, data={"login": self.username, "password": self.password}) # 可选:验证登录是否成功,比如检查响应状态码或返回内容 login_response.raise_for_status() @property def session(self): """获取有效会话:无会话则登录,会话无效则重登""" if not self._session: self._login() return self._session def invalidate_session(self): """标记会话无效,下次使用会触发重新登录""" self._session = None class DataReq: def __init__(self, name, log_sess): self.name = name self.log_sess = log_sess # 共享传入的LogSess实例 def get_data(self): """获取数据,自动处理会话过期重登""" session = self.log_sess.session response = session.post(URL_TDATA, data={"name": self.name}) # 检查是否需要重登:JSON解析失败或响应包含"You must login" try: data = response.json() # 检查响应内容是否要求登录 if isinstance(data, dict) and "You must login" in str(data.values()): raise ValueError("Session requires re-login") return data except (JSONDecodeError, ValueError): # 标记会话无效,重新登录后重试请求 self.log_sess.invalidate_session() session = self.log_sess.session response = session.post(URL_TDATA, data={"name": self.name}) return response.json() # 使用示例 if __name__ == "__main__": # 仅初始化一次LogSess,所有数据请求类共享该实例 my_session = LogSess(username="your_user", password="your_pwd") req1 = DataReq("data1", my_session) req2 = DataReq("data2", my_session) print(req1.get_data()) print(req2.get_data()) # 其他三个同类数据请求类,同样传入my_session实例即可复用会话
关键细节说明
- 会话持久化:
LogSess用_session变量保存会话对象,避免每次新建会话重复执行登录逻辑 - 懒加载登录:
session属性仅在首次调用或会话被标记为无效时,才触发_login方法 - 会话共享:所有数据请求类初始化时接收同一个
LogSess实例,确保复用同一会话 - 自动重登逻辑:当请求返回不可解析的JSON(会话过期常见表现)或包含"You must login"文本时,自动标记会话无效,重新登录后重试请求
- 扩展性:其他三个与
DataReq类似的类,只需按照同样的方式接收LogSess实例,即可复用会话管理和自动重登逻辑
可行性说明
完全可行,这是处理需要登录的API请求的标准方案:
- 会话复用减少了不必要的登录请求,提升了请求效率
- 自动重登逻辑保证了请求的可靠性,无需手动干预
- 代码职责分离清晰:
LogSess专注于会话管理,数据请求类专注于业务数据获取
内容的提问来源于stack exchange,提问作者VERBOSE
相关产品推荐
相关产品推荐

