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

实例化相互依赖对象时如何避免重复登录?

解决方案:实现登录会话的复用与自动重登

核心思路

  • 让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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 16:23:24