围绕嵌套函数定义上下文管理器是否安全?

发布于 2025-01-10 05:49:38 字数 523 浏览 3 评论 0原文

对于第三方库*,我必须提供一个消耗一些数据的函数。我的消费实现需要将数据发布到 API。所以我想出了下面的结构:

def consumer_provider():

    with HttpClient() as http_client:
        
        def consumer(data):
            http_client.post(data)

        return consumer

所以我可以像这样向第三方库展示该函数:

third_party_lib.add(consumer=consumer_provider())

在我的测试中它工作得很好,但是这是合法的吗?我什么时候必须期望上下文管理器释放资源(在本例中为连接池)?

* 在这种情况下是 loguru,但这对于问题来说并不重要

For a third party library* I have to provide a function which consumes some data. My implementation of the consumption requires the data to be posted to an API. So I came up with this structure below:

def consumer_provider():

    with HttpClient() as http_client:
        
        def consumer(data):
            http_client.post(data)

        return consumer

So I can present the function to the third party lib like so:

third_party_lib.add(consumer=consumer_provider())

In my tests it works quite well, but is this legit? When do I have to expect that the context manager releases the resource (in this case the connection pool)?

* loguru in this case, but it should not really matter for the question

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

提笔落墨 2025-01-17 05:49:38

这取决于上下文管理器。在您编写的代码中,您创建的 HTTPClient 保持活动状态,因为它返回的函数保留对它的引用,即使 consumer_provider 中定义的变量 http_client 也是如此。 code> 超出范围。

但是,在 consumer_provider 返回之前仍会调用 HTTPClient.__exit__,因此消费者函数可能无法按预期工作。

您可能想要执行类似的操作

def consumer_provider():
    http_client = HttpClient()
    def consumer(data):
        with http_client:
            http_client.post(data)
    return consumer

,以确保 HttpClient 对象在闭包内保持“隐藏”状态,但其 __enter__ 和 __exit__ 方法不是' t 被调用直到函数被调用。 (客户端是否可以被多个函数调用使用还取决于HttpClient的定义。)

It depends on the context manager. In the code you wrote, the HTTPClient you created stays alive because the function it returns maintains a reference to it, even though the variable http_client defined in consumer_provider goes out of scope.

However, HTTPClient.__exit__ is still called before consumer_provider returns, so the consumer function may not work as intended.

You may want to do something like

def consumer_provider():
    http_client = HttpClient()
    def consumer(data):
        with http_client:
            http_client.post(data)
    return consumer

which ensures that the HttpClient object stays "hidden" inside the closure, but its __enter__ and __exit__ methods aren't called until the function gets called. (Whether the client can be used by multiple function calls also depends on the definition of HttpClient.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文