2017-01-21 11 views
1

Как я могу использовать контекстный менеджер в лямбда? Принимаются хаки. Отложите мнение об этом плохое использование лямбда.Использовать контекстный менеджер в лямбда, как?

Я знаю, что могу это сделать:

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

Но я хотел бы сделать что-то вроде этого:

lambda: with context(): "Foo" 
+0

'f' не является переменной в вашем' lambda'. –

+0

спасибо, синтаксическая ошибка с моей стороны. Исправлена. –

ответ

0

Одним из возможных обходного пути для получения лямбды работы с менеджером контекста, чтобы сделать контекст Менеджером ContextDecorator, то оба with заявления и lambda выражения будут работать, потому что лямбда может использовать шаблон декоратора вместо этого.

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

Вы не можете заменить работу with делает с выражением, нет. Нет никаких хаков, чтобы получить вас там, потому что не существует способа обработать исключения и финализацию внутри выражения.

Это потому, что вы можете использовать только одно выражение в лямбда. with является заявлением , а не выражением. Вам придется заменить его обработкой исключений (try..except..finally) и звонит на __enter__ and __exit__ methods (хранение __exit__сначала). Однако обработка исключений может выполняться только с помощью операторов, поскольку исключение немедленно прекращает текущее выражение. См. Python Try Catch Block inside lambda.

Ваш только вариант должен придерживаться вместо этого правильной функции.

+0

Как насчет ContextDecorator? –

+0

Например, [это] (https://gist.github.com/carlthome/31ba4093a6f7029053de02d70fc48ef1). Есть ли проблема с этим в случае поднятых исключений или чего-то еще? –

+0

А, я забыл об этом. 'ContextDecorator' не является частью выражения лямбда. Он создает новый объект функции, содержащий оператор 'with', затем вызывает исходную функцию и выполняет всю обработку исключений. Это что-то другое. И контекстный менеджер явно должен поддерживать это использование. –