使用 pathlib 模块关闭文件的推荐方法?
Recommended way of closing files using pathlib module?
从历史上看,我一直使用以下方法读取 python
中的文件:
with open("file", "r") as f:
for line in f:
# do thing to line
这仍然是推荐的方法吗?使用以下内容是否有任何缺点:
from pathlib import Path
path = Path("file")
for line in path.open():
# do thing to line
我找到的大多数参考文献都使用 with
关键字打开文件,以便于不必显式关闭文件。这适用于此处的迭代器方法吗?
Pathlib
是面向对象的方式来操作文件系统路径。
使用 pathlib 模块打开文件的推荐方法是使用上下文管理器:
p = Path("my_file.txt")
with p.open() as f:
f.readline()
这确保在使用后关闭文件。
在您提供的两个示例中,您没有关闭文件,因为您打开它们 inplace。
由于 p.open()
returns 文件对象,您可以通过分配它并检查属性 closed
来测试它,如下所示:
from pathlib import Path
path = Path("file.txt")
# Open the file pointed by this path and return a file object, as
# the built-in open() function does.
f = path.open()
for line in f:
# do some stuff
print(f.closed) # Evaluates to False.
请记住,Path
对象用于处理文件系统路径。就像 built-in library of Python, there is an open 方法一样,但在 Path 对象中没有关闭。
.close
位于由内置 open 或使用 Path 对象的打开方法返回的文件句柄中:
>>> from pathlib import Path
>>> p=Path(some_file)
>>> p
PosixPath('/tmp/file')
您可以使用内置的 open 函数或 Path 对象中的 open 方法打开该 Path 对象:
>>> fh=open(p) # open built-in function
>>> fh
<_io.TextIOWrapper name='/tmp/file' mode='r' encoding='UTF-8'>
>>> fh.close()
>>> fh=p.open() # Path open method which aliases to os.open
>>> fh
<_io.TextIOWrapper name='/tmp/file' mode='r' encoding='UTF-8'>
>>> fh.close()
您可以查看 pathlib on Github 的源代码,了解 pathlib
的作者是如何在他们自己的代码中做到这一点的。
我观察到的是三件事之一。
到目前为止最常见的是使用 with
:
from pathlib import Path
p=Path('/tmp/file')
#create a file
with p.open(mode='w') as fi:
fi.write(f'Insides of: {str(p)}')
# read it back and test open or closed
with p.open(mode='r') as fi:
print(f'{fi.read()} closed?:{fi.closed}')
# prints 'Insides of: /tmp/file closed?:False'
您可能知道,在 with
块的末尾调用 __exit__
方法。对于文件,这意味着文件已关闭。这是 pathlib
源代码中最常见的方法。
其次,您还可以在源代码中看到,pathlib 对象维护进入和退出状态以及文件打开和关闭的标志。然而,os.close
函数并未明确调用。您可以使用 .closed
访问器检查该状态。
fh=p.open()
print(f'{fh.read()} closed?:{fh.closed}')
# prints Insides of: /tmp/file closed?:False
# fi will only be closed when fi goes out of scope...
# or you could (and should) do fh.close()
with p.open() as fi:
pass
print(f'closed?:{fi.closed}')
# fi still in scope but implicitly closed at the end of the with bloc
# prints closed?:True
第三,在 cPython 上,当文件句柄超出范围时,文件将关闭。这不可移植或被认为 'good practice' 可以依赖,但通常是这样。在 pathlib 源代码中有这样的实例。
尚未提及的事情:如果您只想读取或写入一些文本(或字节),那么在使用 pathlib 时您不再需要显式使用上下文管理器:
>>> import pathlib
>>> path = pathlib.Path("/tmp/example.txt")
>>> path.write_text("hello world")
11
>>> path.read_text()
'hello world'
>>> path.read_bytes()
b'hello world'
打开文件以迭代行仍应使用 with 语句,原因与将上下文管理器与 open
一起使用的原因相同,如 the docs show:
>>> with path.open() as f:
... for line in f:
... print(line)
...
hello world
从历史上看,我一直使用以下方法读取 python
中的文件:
with open("file", "r") as f:
for line in f:
# do thing to line
这仍然是推荐的方法吗?使用以下内容是否有任何缺点:
from pathlib import Path
path = Path("file")
for line in path.open():
# do thing to line
我找到的大多数参考文献都使用 with
关键字打开文件,以便于不必显式关闭文件。这适用于此处的迭代器方法吗?
Pathlib
是面向对象的方式来操作文件系统路径。
使用 pathlib 模块打开文件的推荐方法是使用上下文管理器:
p = Path("my_file.txt")
with p.open() as f:
f.readline()
这确保在使用后关闭文件。
在您提供的两个示例中,您没有关闭文件,因为您打开它们 inplace。
由于 p.open()
returns 文件对象,您可以通过分配它并检查属性 closed
来测试它,如下所示:
from pathlib import Path
path = Path("file.txt")
# Open the file pointed by this path and return a file object, as
# the built-in open() function does.
f = path.open()
for line in f:
# do some stuff
print(f.closed) # Evaluates to False.
请记住,Path
对象用于处理文件系统路径。就像 built-in library of Python, there is an open 方法一样,但在 Path 对象中没有关闭。
.close
位于由内置 open 或使用 Path 对象的打开方法返回的文件句柄中:
>>> from pathlib import Path
>>> p=Path(some_file)
>>> p
PosixPath('/tmp/file')
您可以使用内置的 open 函数或 Path 对象中的 open 方法打开该 Path 对象:
>>> fh=open(p) # open built-in function
>>> fh
<_io.TextIOWrapper name='/tmp/file' mode='r' encoding='UTF-8'>
>>> fh.close()
>>> fh=p.open() # Path open method which aliases to os.open
>>> fh
<_io.TextIOWrapper name='/tmp/file' mode='r' encoding='UTF-8'>
>>> fh.close()
您可以查看 pathlib on Github 的源代码,了解 pathlib
的作者是如何在他们自己的代码中做到这一点的。
我观察到的是三件事之一。
到目前为止最常见的是使用 with
:
from pathlib import Path
p=Path('/tmp/file')
#create a file
with p.open(mode='w') as fi:
fi.write(f'Insides of: {str(p)}')
# read it back and test open or closed
with p.open(mode='r') as fi:
print(f'{fi.read()} closed?:{fi.closed}')
# prints 'Insides of: /tmp/file closed?:False'
您可能知道,在 with
块的末尾调用 __exit__
方法。对于文件,这意味着文件已关闭。这是 pathlib
源代码中最常见的方法。
其次,您还可以在源代码中看到,pathlib 对象维护进入和退出状态以及文件打开和关闭的标志。然而,os.close
函数并未明确调用。您可以使用 .closed
访问器检查该状态。
fh=p.open()
print(f'{fh.read()} closed?:{fh.closed}')
# prints Insides of: /tmp/file closed?:False
# fi will only be closed when fi goes out of scope...
# or you could (and should) do fh.close()
with p.open() as fi:
pass
print(f'closed?:{fi.closed}')
# fi still in scope but implicitly closed at the end of the with bloc
# prints closed?:True
第三,在 cPython 上,当文件句柄超出范围时,文件将关闭。这不可移植或被认为 'good practice' 可以依赖,但通常是这样。在 pathlib 源代码中有这样的实例。
尚未提及的事情:如果您只想读取或写入一些文本(或字节),那么在使用 pathlib 时您不再需要显式使用上下文管理器:
>>> import pathlib
>>> path = pathlib.Path("/tmp/example.txt")
>>> path.write_text("hello world")
11
>>> path.read_text()
'hello world'
>>> path.read_bytes()
b'hello world'
打开文件以迭代行仍应使用 with 语句,原因与将上下文管理器与 open
一起使用的原因相同,如 the docs show:
>>> with path.open() as f:
... for line in f:
... print(line)
...
hello world