python-3.x 快速更改目录的递归globbing

dfuffjeb  于 2023-05-02  发布在  Python
关注(0)|答案(2)|浏览(136)

我偶然发现了一个不直观的问题:如果递归地(使用pathlib)glob快速更改目录(在此创建和删除其他目录),则有机会获得FileNotFoundException。如果没有找到目录,那为什么要用这个来烦我呢?为什么不跳过伪目录继续呢?我怎么能以一种紧凑的方式绕过这个问题呢?
下面是如何复制它:
使用sh命令启动一个终端

while true; do mkdir deleteme && rmdir deleteme; done

另一个是Python脚本:

from pathlib import Path
p = Path()
while True:
    list(p.rglob('*'))

或者,作为一个链接:

while true; do mkdir 1 && rmdir 1; done & python3 -c "from pathlib import Path; from itertools import count; p = Path(); [list(p.rglob('*')) for i in count(start=1)]"; fg
8xiog9wr

8xiog9wr1#

生成异常的基元是os.scandir
pathlib.Path.rglob()方法创建了一个选择器对象(pathlib._WildcardSelector通过pathlib._make_selector,给定您的模式),然后在rglob()生成器的执行过程中惰性地迭代。
pathlib模块似乎没有给予任何钩子来定制或覆盖此行为。
最好的解决方案可能是子类化PathPosixPath类,覆盖rglob()方法,以一种能够适应这种错误模式的方式重新构建实现。
一个猴子补丁方法,似乎可以作为概念验证:

import contextlib
import pathlib

def my_scandir(path=None):
     while True:
         try:
             result = list(os.scandir(path))
         except FileNotFoundError:
             continue
         @contextlib.contextmanager
         def wrapped_result():
             try:
                 yield result
             finally:
                 pass
         return wrapped_result()

pathlib._NormalAccessor.scandir = staticmethod(my_scandir)

应用此修补程序后,示例中使用rglob('*')执行的while循环在使用FileNotFoundError时不再失败。
这适用于Python v3。8.5.因为它使用了pathlib模块的实现细节,所以它可能不能在其他python版本上工作。

f0brbegy

f0brbegy2#

  • 添加其他可能的解决方案
  • 如果您的快速变化的目录包含隐藏的文件/目录(即.e在unix文件系统中以.开头的目录
  • 然后可以使用glob.globglob.iglob而不是pathlib.Path.glob
  • glob.glob默认忽略隐藏文件/目录。所以它不会打破,如果隐藏的文件/目录被删除中途通过扫描
  • 这将例如与使用文件分段来创建隐藏文件的程序一起工作。例如pyspark创建。Spark-staging文件

相关问题