我正在使用pathlib执行文件操作,大致如下:
for path in Path.cwd().glob("*.ipynb"):
print(path)问题是,这些文件位于外部驱动器上,往往会随机断开连接。因此,glob迭代器抛出一个FileNotFoundError。这是对正在发生的事情的模拟:
def hdd_disconnection_mockup():
for i in range(3):
if i == 1:
raise FileNotFoundError
yield f"Untitled{i}.ipynb">>> for path in hdd_disconnection_mockup():
print(path)
Untitled0.ipynb
FileNotFoundError:我想捕捉这个异常并继续执行for循环。
到目前为止,我已经尝试了以下几点:
def catch_filenotfounderror(glob):
try:
yield next(glob)
except FileNotFoundError:
pass不会引发任何异常,但这并不会阻止glob迭代器中断for循环。
>>> for path in catch_filenotfounderror(hdd_disconnection_mockup()):
print(path)
Untitled0.ipynb预期输出是
Untitled0.ipynb
Untitled2.ipynb发布于 2022-10-19 17:02:02
@Michael Dorner指出:
当生成器抛出异常时,它将退出,您不能继续使用它生成的项。
因此,不可能处理生成器之外的异常。
解决方案
最后,我通过将glob迭代器转换为元组,务实地解决了这个问题。这样,如果在读取路径时出现问题,则在开始时,即进入for循环之前。然后,在for循环中处理异常。
ipynb_paths = Path.cwd().glob("*.ipynb")
for path in tuple(ipynb_paths):
try:
# read from path ...
except FileNotFoundError:
continue失败方法
为了记录在案,我尝试在抛出FileNotFoundError之前创建迭代器的“安全副本”。这个想法是,如果异常发生,我可以让电脑睡一会儿,希望硬盘重新连接,然后用安全拷贝重试。
def catch_filenotfounderror(glob):
while True:
glob, safety_glob = tee(glob, 2)
try:
yield next(glob)
except FileNotFoundError:
sleep(0.1) # Give some time to the HDD to reconnect
glob = safety_glob
except StopIteration:
break不幸的是,安全生成器似乎链接到了它的原始版本,因为它在发生StopIteration的同一时刻引发了一个FileNotFoundError异常。
在这里,这是一个证明这种行为的例子。
class Gen:
exception_thrown = False
@classmethod
def go(cls):
yield "one"
if not cls.exception_thrown:
cls.exception_thrown = True
raise Exception
yield "two"
g1, g2 = tee(Gen.go(), 2)>>> while True:
print(next(g1))
'one'
Exception:>>> while True:
print(next(g2))
'one'
StopIteration:以下是我所期望的行为,假设用tee制作的副本完全断开连接:
>>> for i in Gen.go():
print(i)
'one'
Exception:
>>> for i in Gen.go():
print(i)
'one'
'two'发布于 2022-10-19 13:43:08
我认为这是不可能的:当生成器抛出异常时,它就会退出,并且您不能继续使用它生成的项。
由于您无论如何都不处理异常,所以您可能可以在读取之前检查该文件,以避免FileNotFoundError
from pathlib import Path
my_file = Path('/path/to/file')
if my_file.exists():
# read filehttps://stackoverflow.com/questions/74124836
复制相似问题