Python os.walk,保存状态的方法?
我需要迭代文件服务器上的所有文件,并且我希望能够停止该过程,并在稍后的时间在文件树中的任何位置恢复该过程。这可以通过os.walk实现,还是需要从头开始实现Python os.walk,保存状态的方法?,python,python-2.7,Python,Python 2.7,我需要迭代文件服务器上的所有文件,并且我希望能够停止该过程,并在稍后的时间在文件树中的任何位置恢复该过程。这可以通过os.walk实现,还是需要从头开始实现 编辑:理想情况下,我希望解决方案是持久的,这样脚本就可以停止并稍后重新启动。os.walk是一个非常正常的生成器函数,这意味着您可以调用它,保存生成的生成器,并在空闲时对其进行迭代。例如: w = os.walk(root) for root, dirs, files in w: if root == 'foo': b
编辑:理想情况下,我希望解决方案是持久的,这样脚本就可以停止并稍后重新启动。
os.walk
是一个非常正常的生成器函数,这意味着您可以调用它,保存生成的生成器,并在空闲时对其进行迭代。例如:
w = os.walk(root)
for root, dirs, files in w:
if root == 'foo':
break
else:
# usual stuff
print('Hey, we found foo')
for root, dirs, files in w:
# usual stuff
您甚至可以w
到函数,或者从函数返回它,或者将它作为迭代器与您喜爱的itertools
函数一起使用,等等
你不能用它做的一件大事就是腌制它。因此,如果您想将其持久化到磁盘(或数据库),这样您就可以退出程序并从停止的地方继续,或者将其发送到子进程以完成,或者诸如此类,您不能这样做 如果您可以提前完成整个步行,而不是懒散地完成(即,您不需要动态修剪步行,步行本身所需的时间和存储空间与实际工作所需的时间和存储空间相比相形见绌),那么您可以坚持
list(w)
。然后,您只需跟踪该列表以及到目前为止得到的索引(或者只需持久化wlist[index://code>,而不是wlist
和index
)。但对于某些用例,这是不可接受的
幸运的是,walk
是用纯Python实现的,而且非常简单,因此您可以从中复制代码并对其进行修改,以使状态持久化。问题在于,通过yield
的魔力,状态部分是隐式的,因此您必须将生成器从内到外转换,或者将其转换为等效的纯迭代解决方案。这是一个开始:
class Walk(object):
def __init__(self, top):
self.queue = [top]
def __iter__(self):
return self
def __next__(self):
top = self.queue.pop(0)
names = os.listdir(top)
dirs, nondirs = [], []
for name in names:
if os.path.isdir(os.path.join(top, name)):
dirs.append(name)
else:
nondirs.append(name)
self.queue.extend(os.path.join(top, dir) for dir in dirs)
return top, dirs, nondirs
这不处理任何可选参数followlinks=False
和onerror
是微不足道的。处理top-down=True
的动态修剪并不复杂(只需隐藏top
和dirs
,并在下一次调用开始时而不是在本次调用结束时将子项排队)。执行top-down=False
会有点痛苦,但仍然不算太糟糕(您可以为标准的递归到迭代转换创建一个显式的状态堆栈,或者保留额外的数据,或者只是创建、隐藏和迭代一个新的Walk
对象列表)。如果你不需要它们,不要费心添加它们
我相信这将不会改变。(如果不是,它要么是一个微不足道的\uuu getstate\uuu
,要么是一个几乎微不足道的\uuuu reduce\uuuu
,远离工作状态。)如果您使用的是不同的持久化机制,实际上,您需要持久化的只是这是一个Walk
对象,其队列是self.queue
(这只是一个字符串列表),所以这应该很容易。是否不希望在行走之间更改目录结构?它可能会更改,但我不介意丢失新创建/删除的文件。我可以在以后再次运行它以拾取任何丢失的文件。您希望在一次运行中保存状态,或者希望能够将其持久化到磁盘(或数据库或其他任何位置),以便退出并重新启动并重新拾取漫游?我正在设想某种持久化。由于我没有考虑过的一些罕见的情况,或者由于不稳定的网络连接,脚本偶尔会崩溃。这取决于您的用例。你可能想试着做列表
的事情,然后把它藏起来(用pickle
,或者csv
,或者任何合适的东西),看看它需要多少时间和空间。是的,我希望有某种持久性。