我有一个for循环,它运行一个目录并处理那里的文件,但我想一次只处理一定数量的文件。例如,我有一个包含1000个文件的目录,但我每天只能处理250个文件,因此第一次运行脚本时,它会处理前250个,然后是下一个250,依此类推。依此类推。 / p>
首先,我正在检查文件名,该文件记录了已经同步的文件的名称,因此我不会再次处理它们。然后我想处理下面的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个文件的数量。我应该将range语句添加到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)
还是有更简单的方法吗?谢谢。
答案 0 :(得分: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')
而不是使用简单的文件匹配器;测试归结为同样的事情。