Как использовать Python closing context manager

#python #file-io #with-statement

#python #file-io #с помощью-statement

Вопрос:

Функция стандартной библиотеки open работает как функция:

 f = open('file.txt')
print(type(f))
<type 'file'>
  

или как контекстный менеджер:

 with open('file.txt') as f:
    print(type(f))
<type 'file'>
  

Я пытаюсь имитировать это поведение, используя contextlib.closing , где File находится мой пользовательский класс ввода-вывода файла:

 def my_open(filename):
    f = File(filename)
    f.open()
    return closing(f)
  

это работает так, как ожидалось, как контекстный менеджер:

 with my_open('file.txt') as f:
    print(type(f))
<class '__main__.File'>
  

но, конечно, если я вызываю напрямую, я получаю обратно closing объект вместо моего объекта:

 f = my_open(filename)
print(type(f))
<class 'contextlib.closing'>
  

Итак, как мне реализовать, my_open чтобы он работал как context manager и возвращал мой файловый объект при прямом вызове?

Полный рабочий пример на github: https://gist.github.com/1352573

Комментарии:

1. Это не то, closing для чего. Вы используете closing при написании with , чтобы превратить любой объект с close методом в контекстный менеджер. Вы не используете его заранее. Пример в contextlib документах кажется довольно понятным. Если вы хотите иметь возможность превратить его в контекстный менеджер в любое время, тогда ответ Зака правильный.

Ответ №1:

Вероятно, проще всего реализовать методы __enter__ и __exit__ самостоятельно. Что-то вроде этого должно это сделать:

 class File(object):
   # ... all the methods you already have ...

   # context management
   def __enter__(self):
       return self

   def __exit__(self, *exc_info):
       self.close()
  

Кстати, было бы более идиоматично выполнять работу вашего open метода в вашем __init__ методе.

Комментарии:

1. Также возможно — просто выполните close работу в __exit__ и сделайте close = __exit__ , или наоборот.