Встроенный open()
может использоваться как функция или как менеджер контекста.
f = open(filename)
f.read()
with open(filename) as f:
f.read()
Я хотел бы написать свою собственную функцию, которая также может использоваться обоими способами.Для простоты примера, скажем, я хочу реализовать функцию myopen()
.
Что не работает:
Простая функция с контекстным оформлением:
@contextlib.contextmanager
def myopen(filename):
try:
f = open(filename)
yield f
finally:
f.close()
>>> myopen(somefile)
<contextlib.GeneratorContextManager at 0x2b6bf7727610>
он возвращает GeneratorContextManager
вместо объекта файла.
Класс контекста:
class myopen(object):
def __init__(self, filename):
self.filename = filename
self.file = None
def __enter__(self):
self.file = open(filename)
return self.file
def __exit__(self):
self.file.close()
def __call__(filename):
return open(filename)
>>> myopen(somefile)
__main__.myopen
Вызов класса, очевидно, создает экземпляр, как и должно быть.Мне пришлось бы создать экземпляр и вызвать его (f = myopen(somefile)()
).