【问题标题】:Using requests.Session() in Python as a context manager for a variable number of consecutive requests在 Python 中使用 requests.Session() 作为可变数量连续请求的上下文管理器
【发布时间】:2018-08-23 03:05:46
【问题描述】:

我想使用一个对象作为上下文管理器,但要控制调用__exit__ 方法的时间。

特别是,我正在使用 Python requests 模块提供的Session() 对象,它可以用作上下文管理器。我通过简单地使用例如来理解这一点。 requests.get() 每次都会创建和销毁一个新的 Session() 对象,而持久化会话应该提供更短的响应时间并为会话中的所有请求保留标头等。我想用Session() 发出x 请求,然后关闭会话并用新的Session() 对象发出y 请求,依此类推,直到我的代码完成运行。但是,由于我在代码中对Session().get() 进行了各种调用,因此我不想将其全部包含在with 块中。我有哪些选择?

对于更有经验的 Python 程序员来说,这可能是一个简单的问题,但我发现自己陷入了弄清楚如何组织我的代码的困境。关于如何实施的任何想法?如果需要,很乐意提供任何澄清。谢谢。

【问题讨论】:

    标签: python session python-requests contextmanager


    【解决方案1】:

    请注意,调用 Session() 总是会创建一个新的 Python 对象,这里是一个 requests 会话。这意味着如果你有,就像你说的那样

    在我的代码中对 Session().get() 的各种调用

    那么你必须每次都创建一个新的 Session 对象。没有办法用魔法来包装你的代码来重用同一个会话。您有两个主要解决方案。

    1。创建一个会话对象并重用它。

    因为您的代码可能看起来像这样(其中创建了三个独立的会话):

    Session().get(...)
    # ...
    Session().get(...)
    # ...
    Session().get(...)
    

    相反,创建一个会话,每次都重复使用它。你需要修改你的代码:

    mysession = Session() # create a new session
    
    mysession.get(...)
    # ...
    mysession.get(...) # session is reused
    # ...
    mysession.get(...) # session is reused
    
    # finished with session, make sure to close it!
    mysession.close()
    

    这避免了将所有内容放在with 块中。

    2。将您的代码放在with 块中。

    with requests.Session() as s:
        s.get(...)
        s.get(...)
        s.get(...)
    # session s automatically closed here
    

    documentation 中所述,with 上下文管理器

    将确保会话在退出 with 块后立即关闭,即使发生未处理的异常。

    这是主要的好处 - 您不必记得关闭会话,这很容易忘记,尤其是在您发出大量请求时。

    您注意到您不希望将所有内容都包含在with 块中。一项建议是在 with 块中处理所有请求,然后在块外处理生成的响应。这将 a) 将您的代码分成“获取远程数据”和“处理远程数据”部分,使其更易于阅读,但是,如果不查看您的代码/逻辑,这可能是不可能的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-22
      • 2018-02-05
      • 1970-01-01
      相关资源
      最近更新 更多