用1行代码打开读取和关闭文件

问题:用1行代码打开读取和关闭文件

现在我使用:

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

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

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

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

Now I use:

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

But to make the code look better, I can do:

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

When using the above syntax, how do I close the file to free up system resources?


回答 0

您实际上不必关闭它-Python将在垃圾回收期间或程序退出时自动完成它。但是正如@delnan指出的,出于各种原因,最好将其显式关闭。

因此,可以做些什么来使其简短,简单和明确:

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

我认为,现在只有两行并且可读性强。

You don’t really have to close it – Python will do it automatically either during garbage collection or at program exit. But as @delnan noted, it’s better practice to explicitly close it for various reasons.

So, what you can do to keep it short, simple and explicit:

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

Now it’s just two lines and pretty readable, I think.


回答 1

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上安装反向移植pathlibpathlib2

Python Standard Library Pathlib module does what you looking for:

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

Don’t forget to import Path:

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'

On Python 27 install backported pathlib or pathlib2


回答 2

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

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

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

最好再投资一条线:

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

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

Using CPython, your file will be closed immediately after the line is executed, because the file object is immediately garbage collected. There are two drawbacks, though:

  1. In Python implementations different from CPython, the file often isn’t immediately closed, but rather at a later time, beyond your control.

  2. In Python 3.2 or above, this will throw a ResourceWarning, if enabled.

Better to invest one additional line:

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

This will ensure that the file is correctly closed under all circumstances.


回答 3

无需导入任何特殊的库即可执行此操作。

使用常规语法,它将打开文件进行读取,然后将其关闭。

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

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

No need to import any special libraries to do this.

Use normal syntax and it will open the file for reading then close it.

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

or

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

which gives you an array x containing the lines, and can be printed like so:

for line in x: print line

These one-liners are very helpful for maintenance – basically self-documenting.


回答 4

您可以做的是使用该with语句,并在一行上写下两个步骤:

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

with语句将谨慎地调用__exit__给定对象的函数,即使代码中发生了一些问题;它接近try... finally语法。对于由返回的对象open__exit__对应于文件关闭。

该语句已在Python 2.6中引入。

What you can do is to use the with statement, and write the two steps on one line:

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

The with statement will take care to call __exit__ function of the given object even if something bad happened in your code; it’s close to the try... finally syntax. For object returned by open, __exit__ corresponds to file closure.

This statement has been introduced with Python 2.6.


回答 5

使用ilio:(inline io):

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

from ilio import read

content = read('filename')

use ilio: (inline io):

just one function call instead of file open(), read(), close().

from ilio import read

content = read('filename')

回答 6

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

回答 7

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

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

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

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

I think the most natural way for achieving this is to define a function.

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

Then you can do the following:

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

回答 8

当我需要在日志文件中抓取一些内容时,我经常这样做:

$ 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

I frequently do something like this when I need to get a few lines surrounding something I’ve grepped in a log file:

$ 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

使用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

Using more_itertools.with_iter, it is possible to open, read, close and assign an equivalent output in one line (excluding the import statement):

import more_itertools as mit


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

Although possible, I would look for another approach other than assigning the contents of a file to a variable, i.e. lazy iteration – this can be done using a traditional with block or in the example above by removing join() and iterating output.


回答 10

如果你想要的温暖和模糊的感觉,只是去用

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

If you want that warm and fuzzy feeling just go with with.

For python 3.6 I ran these two programs under a fresh start of IDLE, giving runtimes of:

0.002000093460083008  Test A
0.0020003318786621094 Test B: with guaranteed close

So not much of a difference.

#--------*---------*---------*---------*---------*---------*---------*---------*
# 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

OUTPUT:

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

OUTPUT:

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