简体   繁体   English

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

[英]Use context manager in lambda, how?

How can I use a context manager in a lambda? 如何在Lambda中使用上下文管理器? Hacks accepted. 黑客接受。 Defer opinions about this being a bad usage of lambdas. 推迟对此的意见,因为这是lambda的错误用法。

I know I can do this: 我知道我可以这样做:

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

But I would like to do something like this: 但是我想做这样的事情:

lambda: with context(): "Foo"

You can't replace the work with does with an expression, no. 你不能更换工作with与表达式不,没有。 There are no hacks to get you there either, because there is no way to handle exceptions and finalisation within an expression. 也没有技巧可以使您到达那里,因为无法处理表达式中的异常和终结处理。

That's because you can only use one expression in a lambda. 那是因为您只能在lambda中使用一个表达式 with is a statement , not an expression. with是一个语句 ,而不是一个表达式。 You'd have to replace that with exception handling ( try..except..finally ) and calls to the __enter__ and __exit__ methods (storing the __exit__ method first ). 你必须更换与异常处理( try..except..finally ),并调用到__enter____exit__方法 (存储__exit__ 一种方法)。 However, exception handling can only be done with statements, because an exception ends the current expression immediately. 但是,异常处理只能使用语句来完成,因为异常会立即结束当前表达式。 See Python Try Catch Block inside lambda . 请参阅lambda中的Python Try Catch Block

Your only option is to stick to using a proper function instead. 唯一的选择是坚持使用适当的功能。

One possible workaround for getting lambdas working with a context manager is to make the context manager a ContextDecorator , then both with statements and lambda expressions will work because a lambda can use the decorator pattern instead. 用于获取lambda表达式与上下文管理工作的一个可能的解决方法是使上下文经理ContextDecorator ,那么这两个with语句和lambda表达式将工作,因为lambda可以使用Decorator模式来代替。

Example

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'))()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM