открыть прочитать и закрыть файл в 1 строку кода
теперь я использую:
pageHeadSectionFile = open('pagehead.section.htm','r')
output = pageHeadSectionFile.read()
pageHeadSectionFile.close()
но чтобы код выглядел лучше, я могу сделать:
output = open('pagehead.section.htm','r').read()
при использовании вышеуказанного синтаксиса, как закрыть файл, чтобы освободить системные ресурсы?
11 ответов
вам действительно не нужно закрывать его-Python сделает это автоматически либо во время сбора мусора, либо при выходе из программы. Но ,как отметил @ delnan, лучше явно закрыть его по разным причинам.
Итак, что вы можете сделать, чтобы держать его коротким, простым и понятным:
with open('pagehead.section.htm','r') as f:
output = f.read()
теперь это всего две строки и довольно читабельные, я думаю.
Стандартная Библиотека 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'
используя CPython, ваш файл будет закрыт сразу же после выполнения строки, потому что объект file немедленно собирает мусор. Однако есть два недостатка:--3-->
в реализациях Python, отличных от CPython, файл часто не сразу закрывается, а скорее позже, вне вашего контроля.
в Python 3.2 или выше это вызовет
ResourceWarning
, если включена.
лучше инвестируйте одну дополнительную строку:
with open('pagehead.section.htm','r') as f:
output = f.read()
Это гарантирует, что файл будет правильно закрыт при любых обстоятельствах.
что вы можете сделать, это использовать with
о себе:
>>> with open('pagehead.section.htm', 'r') as fin:
... output = fin.read()
на with
оператор позаботится о вызове __exit__
функция данного объекта, даже если что-то плохое произошло в вашем коде; это близко к try... finally
синтаксис. Для объекта, возвращаемого open
, __exit__
соответствует закрытию файла.
это утверждение было введено с Python 2.6.
использовать подвздошно: (inline io):
только один вызов функции вместо файла open(), read (), close ().
from ilio import read
content = read('filename')
не нужно импортировать какие-либо специальные библиотеки для этого.
используйте обычный синтаксис, и он откроет файл для чтения, а затем закройте его.
with open("/etc/hostname","r") as f: print f.read()
или
with open("/etc/hosts","r") as f: x = f.read().splitlines()
который дает вам массив x, содержащий строки, и может быть напечатан следующим образом:
for i in range(len(x)): print x[i]
эти ОДН-вкладыши очень полезны для обслуживания-по существу собственн-документировать.
Я часто делаю что-то подобное, когда мне нужно получить несколько строк, окружающих то, что я захватил в файле журнала:
$ grep -n "xlrd" requirements.txt | awk -F ":" '{print }'
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
используя more_itertools.with_iter
, можно открыть, прочитать, закрыть и назначить эквивалентную output
в одной строке (исключая инструкцию import):
import more_itertools as mit
output = "".join(line for line in mit.with_iter(open("pagehead.section.htm", "r")))
хотя это возможно, я бы искал другой подход, кроме назначения содержимого файла переменной, т. е. ленивую итерацию - это можно сделать с помощью традиционного with
блок или в примере выше, путем удаления join()
и переборе output
.
если вы хотите, чтобы это теплое и нечеткое чувство просто пойти с С.
для python 3.6 я запустил эти две программы при новом запуске простоя, давая время выполнения:
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.
меня не волнует, что где-то хранится простая функция, которую я пишу только один раз в жизни:
def readAndClose(fileName):
f = open(filename,'r')
val = f.read()
f.close()
return val
тогда остальное довольно просто:
textFromFile = readAndClose(fileName)