在 lambda 中使用上下文管理器,如何?

问题描述 投票:0回答:3

如何在 lambda 中使用上下文管理器?接受黑客攻击。推迟对 lambda 的错误使用的看法。

我知道我能做到:

def f():
    with context():
        return "Foo"

但我想做这样的事情:

lambda: with context(): "Foo"
python lambda with-statement contextmanager
3个回答
4
投票

你不能用表达式代替

with
所做的工作,不。也没有任何技巧可以帮助您实现这一目标,因为无法在表达式中处理异常和终结。

那是因为您只能在 lambda 中使用一个表达式

with
是一个 陈述,而不是表达式。您必须将其替换为异常处理 (
try..except..finally
) 并调用
__enter__
__exit__
方法
(存储
__exit__
方法 first)。但是,异常处理只能通过语句来完成,因为异常会立即结束当前表达式。请参阅 lambda 中的 Python Try Catch 块

唯一的选择

是坚持使用正确的函数。


3
投票
ContextDecorator

,然后

with
语句和
lambda
表达式都可以工作,因为 lambda 可以使用装饰器模式。

示例

from contextlib import ContextDecorator def f(x): """Just prints the input, but this could be any arbitrary function.""" print(x) class mycontext(ContextDecorator): def __enter__(self): f('Starting') return self def __exit__(self, *exc): f('Finishing') return False with mycontext(): f('The bit in the middle') mycontext()(lambda: f('The bit in the middle'))()



0
投票
with

语句上使用包装函数,如下所示:

from typing import TypeVar
from contextlib import AbstractContextManager
from collections.abc import Callable

T = TypeVar("T"); V = TypeVar("V")
def _with(ctx: AbstractContextManager[T], action: Callable[[T], V]) -> V:
    with ctx as c: return action(c)

_with(context(), lambda c: "Foo")

	
© www.soinside.com 2019 - 2024. All rights reserved.