围绕嵌套函数定义上下文管理器是否安全?
对于第三方库*,我必须提供一个消耗一些数据的函数。我的消费实现需要将数据发布到 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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这取决于上下文管理器。在您编写的代码中,您创建的
HTTPClient
保持活动状态,因为它返回的函数保留对它的引用,即使consumer_provider
中定义的变量http_client
也是如此。 code> 超出范围。但是,在
consumer_provider
返回之前仍会调用HTTPClient.__exit__
,因此消费者函数可能无法按预期工作。您可能想要执行类似的操作
,以确保 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 variablehttp_client
defined inconsumer_provider
goes out of scope.However,
HTTPClient.__exit__
is still called beforeconsumer_provider
returns, so the consumer function may not work as intended.You may want to do something like
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 ofHttpClient
.)