#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__
, или наоборот.