Если вы просто запустите Python и использовать любой из этих вариантов, чистый эффект такой же если базовый экземпляр file
объекта в Python не изменяется. (В один вариант, файл закрыт только когда file_obj
выходит из области против в конце блока во втором варианте, как вы уже заметили.)
Там могут быть различия с прецедентами с context manager однако , Поскольку file
является объектом, вы можете изменить его или подклассифицировать.
Вы также можете открыть файл, просто вызывая file(file_name)
показывая, что file
действует, как и другие объекты (но никто не открывает файлы, путь в Python, если он не будет с with
):
>>> f=open('a.txt')
>>> f
<open file 'a.txt', mode 'r' at 0x1064b5ae0>
>>> f.close()
>>> f=file('a.txt')
>>> f
<open file 'a.txt', mode 'r' at 0x1064b5b70>
>>> f.close()
В более общем , открытие и закрытие некоторого ресурса, называемого the_thing
(обычно это файл, но может быть любым), вы выполняете следующие действия:
set up the_thing # resource specific, open, or call the obj
try # generically __enter__
yield pieces from the_thing
except
react if the_thing is broken
finally, put the_thing away # generically __exit__
Вы можете с легкостью изменить поток этих подэлементов, используя контекстный менеджер и процедурный код, сплетенный между open
и другими элементами кода.
Поскольку Python 2.5, файловые объекты имеют __enter__ и __exit__ методы:
>>> f=open('a.txt')
>>> f.__enter__
<built-in method __enter__ of file object at 0x10f836780>
>>> f.__exit__
<built-in method __exit__ of file object at 0x10f836780>
по умолчанию Python file
объект использует эти методы в этой моде:
__init__(...) # performs initialization desired
__enter__() -> self # in the case of `file()` return an open file handle
__exit__(*excinfo) -> None. # in the case of `file()` closes the file.
Эти методы могут быть изменены для собственных использовать для изменения способа обработки ресурса при его открытии или закрытии. Менеджер контекста делает это действительно простым, чтобы изменить, что происходит, когда вы открываете или закрываете файл.
тривиальный пример:
class Myopen(object):
def __init__(self, fn, opening='', closing='', mode='r', buffering=-1):
# set up the_thing
if opening:
print(opening)
self.closing=closing
self.f=open(fn, mode, buffering)
def __enter__(self):
# set up the_thing
# could lock the resource here
return self.f
def __exit__(self, exc_type, exc_value, traceback):
# put the_thing away
# unlock, or whatever context applicable put away the_thing requires
self.f.close()
if self.closing:
print(self.closing)
Теперь попробуйте следующее:
>>> with Myopen('a.txt', opening='Hello', closing='Good Night') as f:
... print f.read()
...
Hello
[contents of the file 'a.txt']
Good Night
После того, как у вас есть контроль входа и выхода на ресурс, есть много случаев использования:
- замок ресурс для доступа к нему и его использования; разблокировать, когда вы закончите
- Сделать причудливый ресурс (например, файл памяти, базу данных или веб-страницу) более похожим на прямой файловый ресурс
- Открыть базу данных и откат, если есть исключение, но совершить все записи, если есть без ошибок
- Временно изменить контекст вычисления с плавающей запятой
- времени куска кода
- изменения исключений, которые вы поднимаете, возвращая
True
или False
от метода __exit__.
Вы можете прочитать больше примеров в PEP 343.
... Я не уверен. Время, чтобы запустить сеанс REPL Python и посмотреть, есть ли разница! – ArtOfWarfare
Это оба примера контекстного открытия файла. Это в основном позволяет автоматически закрывать файл, когда вы больше не находитесь в контексте файла, который читается/записывается. –
Не совсем те же вопросы, но могут помочь: http://stackoverflow.com/questions/1369526/what-is-the-python-keyword-with-used-for и http://stackoverflow.com/questions/3012488/what-is-the-python-with-statement-designed-for – tomasyany