1

我有一个 for 循环,它遍历一个目录并处理那里的文件,但我想一次只处理一定数量的文件。例如,我有一个包含 1000 个文件的目录,但我每天只能处理 250 个文件,所以我第一次运行脚本时,它会处理前 250 个文件,然后处理下一个 250 个文件,依此类推。

首先,我将根据记录已同步文件名称的 XML 文件检查文件名,这样我就不会再次处理它们。然后我想处理接下来的 n 个文件,其中我有一个变量synclimit = n

我考虑将 in range 语句添加到 for 循环中,如下所示:

tree = ET.parse("sync_list.xml")
root = tree.getroot()
synced = [elt.text for elt in root.findall('synced/sfile')]
for filename in os.listdir(filepath) and in range (0, synclimit) :
    if fnmatch.fnmatch(filename, '*.txt') and filename not in synced:
    filename = os.path.join(filepath, filename)
    result = plistlib.readPlist(filename)

但是,我很确定这只会每次检查目录中的前 n 个文件。我应该将范围语句添加到 if 语句吗?喜欢:

tree = ET.parse("sync_list.xml")
root = tree.getroot()
synced = [elt.text for elt in root.findall('synced/sfile')]
for filename in os.listdir(filepath):
    if fnmatch.fnmatch(filename, '*.txt') and filename not in synced and in range (0, synclimit):
    filename = os.path.join(filepath, filename)
    result = plistlib.readPlist(filename)

还是有更简单的方法来做到这一点?谢谢你。

4

1 回答 1

1

只需保留一个单独的计数器并增加它,然后测试它是否已达到synclimit. 就那么简单。这里不需要太聪明:

processed = 0
for filename in os.listdir(filepath):
    if not filename.endswith('.txt') or filename in synched:
        continue
    # process
    processed += 1
    if processed >= synclimit:
        break  # done for today.

或者,由于os.listdir()返回一个列表,如果您已经在一组文件名中同步了列表,则可以对其进行过滤,然后将其切成最大大小:

synced = set(elt.text for elt in root.findall('synced/sfile'))
to_process = [f for f in os.listdir(filepath) if f.endswith('.txt') and f not in synched]

for filename in to_process[:synclimit]:
    # process

请注意,我只是测试.endswith('.txt')而不是使用您的简单文件匹配器;测试归结为同一件事。

于 2012-11-22T16:35:17.400 回答