打开读取并关闭1行代码中的文件

时间:2011-11-04 15:34:25

标签: python readfile

现在我用:

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

但为了让代码看起来更好,我可以这样做:

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

使用上述语法时,如何关闭文件以释放系统资源?

11 个答案:

答案 0 :(得分:158)

你真的不必关闭它 - Python会在垃圾收集或程序退出时自动执行。但正如@delnan所指出的那样,出于各种原因明确关闭它是更好的做法。

那么,你可以做些什么来保持简短,明确:

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

现在它只是两行而且非常易读。我想。

答案 1 :(得分:33)

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 27上安装backported pathlibpathlib2

答案 2 :(得分:19)

使用CPython,您的文件将在执行该行后立即关闭,因为文件对象会立即被垃圾回收。但是有两个缺点:

  1. 在与CPython不同的Python实现中,该文件通常不会立即关闭,而是在以后的时间内,超出您的控制范围。

  2. 在Python 3.2或更高版本中,如果启用,则会抛出ResourceWarning

  3. 最好再投资一条线:

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

    这将确保在所有情况下都能正确关闭文件。

答案 3 :(得分:11)

无需导入任何特殊库来执行此操作。

使用普通语法,它会打开文件进行阅读然后将其关闭。

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

这些单行程序对维护非常有帮助 - 基本上是自我记录。

答案 4 :(得分:9)

您可以使用with声明:

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

即使代码中发生了错误,with语句也会调用给定对象的__exit__函数;它接近try... finally语法。对于open返回的对象,__exit__对应于文件关闭。

此声明已在Python 2.6中引入。

答案 5 :(得分:5)

使用ilio :(内联io):

只有一个函数调用而不是文件open(),read(),close()。

from ilio import read

content = read('filename')

答案 6 :(得分:3)

with open('pagehead.section.htm')as f:contents=f.read()

答案 7 :(得分:1)

我认为实现此目标的最自然的方法是定义一个函数。

def read(filename):
    f = open(filename, 'r')
    output = f.read()
    f.close()
    return output

然后您可以执行以下操作:

output = read('pagehead.section.htm')

答案 8 :(得分:0)

当我需要在日志文件中插入一些内容时,我经常做这样的事情:

$ 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

答案 9 :(得分:0)

使用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块完成,或者在上面的示例中通过删除{{ 1}}并迭代join()

答案 10 :(得分:0)

如果您想要那种温暖而模糊的感觉,只需使用

对于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.