открыть чтение и закрыть файл в 1 строке кода - PullRequest
101 голосов
/ 04 ноября 2011

Теперь я использую:

pageHeadSectionFile = open('pagehead.section.htm','r')
output = pageHeadSectionFile.read()
pageHeadSectionFile.close()

Но чтобы код выглядел лучше, я могу сделать:

output = open('pagehead.section.htm','r').read()

При использовании приведенного выше синтаксиса, как закрыть файл наосвободить системные ресурсы?

Ответы [ 10 ]

164 голосов
/ 04 ноября 2011

Вам не нужно закрывать его - Python сделает это автоматически либо во время сборки мусора, либо при выходе из программы. Но, как заметил @delnan, лучше явным образом закрывать его по разным причинам.

Итак, что вы можете сделать, чтобы оно было коротким, простым и понятным:

with open('pagehead.section.htm','r') as f:
    output = f.read()

Теперь это всего две строки, и я думаю, что они довольно читабельны.

34 голосов
/ 11 ноября 2016

Стандартная библиотека Python Модуль Pathlib делает то, что вы ищете:

Path('pagehead.section.htm').read_text()

Не забудьте импортировать путь:

jsk@dev1:~$ python3
Python 3.5.2 (default, Sep 10 2016, 08:21:44)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from pathlib import Path
>>> (Path("/etc") / "hostname").read_text()
'dev1.example\n'

При установке на Python 27backported pathlib или pathlib2

19 голосов
/ 04 ноября 2011

Используя CPython, ваш файл будет закрыт сразу же после выполнения строки, потому что объект файла немедленно удаляется сборщиком мусора. Однако есть два недостатка:

  1. В реализациях Python, отличных от CPython, файл часто закрывается не сразу, а в более позднее время, вне вашего контроля.

  2. В Python 3.2 или выше, будет выброшено ResourceWarning, если включено.

Лучше инвестировать одну дополнительную линию:

with open('pagehead.section.htm','r') as f:
    output = f.read()

Это обеспечит правильное закрытие файла при любых обстоятельствах.

11 голосов
/ 10 сентября 2017

Нет необходимости импортировать специальные библиотеки для этого.

Используйте обычный синтаксис, и файл откроется для чтения, а затем закроется.

with open("/etc/hostname","r") as f: print f.read() 

или

with open("/etc/hosts","r") as f: x = f.read().splitlines()

, который дает вам массив x, содержащий строки, и может быть напечатан следующим образом:

for line in x: print line

Эти однострочники очень полезны для обслуживания - в основном этодокументированию.

9 голосов
/ 04 ноября 2011

Что вы можете сделать, это использовать оператор with:

>>> with open('pagehead.section.htm', 'r') as fin:
...     output = fin.read()

Оператор with позаботится о вызове __exit__ функции данного объекта, даже если что-то плохое произошло вкод;это близко к синтаксису try... finally.Для объекта, возвращаемого open, __exit__ соответствует закрытию файла.

Это утверждение было введено в Python 2.6.

5 голосов
/ 21 августа 2015

использование ilio : (inline io):

только один вызов функции вместо открытия (), чтения (), закрытия ().

from ilio import read

content = read('filename')
3 голосов
/ 23 декабря 2016
with open('pagehead.section.htm')as f:contents=f.read()
0 голосов
/ 01 февраля 2018

Если вы хотите это теплое и пушистое чувство, просто используйте с .

Для Python 3.6 я запустил эти две программы при новом запуске IDLE, дав время выполнения:

0.002000093460083008  Test A
0.0020003318786621094 Test B: with guaranteed close

Так что особой разницы нет.

#--------*---------*---------*---------*---------*---------*---------*---------*
# Desc: Test A for reading a text file line-by-line into a list
#--------*---------*---------*---------*---------*---------*---------*---------*

import sys
import time

#                                  # MAINLINE
if __name__ == '__main__':
    print("OK, starting program...")

    inTextFile = '/Users/Mike/Desktop/garbage.txt'

#                                  # Test: A: no 'with;
    c=[]
    start_time = time.time()
    c = open(inTextFile).read().splitlines()
    print("--- %s seconds ---" % (time.time() - start_time))

    print("OK, program execution has ended.")
    sys.exit()                     # END MAINLINE

ВЫВОД:

OK, starting program...
--- 0.002000093460083008 seconds ---
OK, program execution has ended.

#--------*---------*---------*---------*---------*---------*---------*---------*
# Desc: Test B for reading a text file line-by-line into a list
#--------*---------*---------*---------*---------*---------*---------*---------*

import sys
import time

#                                  # MAINLINE
if __name__ == '__main__':
    print("OK, starting program...")

    inTextFile = '/Users/Mike/Desktop/garbage.txt'

#                                  # Test: B: using 'with'
    c=[]
    start_time = time.time()
    with open(inTextFile) as D: c = D.read().splitlines()
    print("--- %s seconds ---" % (time.time() - start_time))

    print("OK, program execution has ended.")
    sys.exit()                     # END MAINLINE

ВЫВОД:

OK, starting program...
--- 0.0020003318786621094 seconds ---
OK, program execution has ended.
0 голосов
/ 29 августа 2017

Используя more_itertools.with_iter, можно открывать, читать, закрывать и назначать эквивалент output в одну строку (исключая оператор импорта):

import more_itertools as mit


output = "".join(line for line in mit.with_iter(open("pagehead.section.htm", "r")))

Хотявозможно, я бы искал другой подход, кроме присвоения содержимого файла переменной, то есть ленивую итерацию - это можно сделать с помощью традиционного блока with или в примере выше, удалив join() и итерировав output.

0 голосов
/ 06 февраля 2015

Я часто делаю что-то подобное, когда мне нужно получить несколько строк, окружающих что-то, что я нашел в файле журнала:

$ grep -n "xlrd" requirements.txt | awk -F ":" '{print $1}'
54

$ python -c "with open('requirements.txt') as file: print ''.join(file.readlines()[52:55])"
wsgiref==0.1.2
xlrd==0.9.2
xlwt==0.7.5
...