在Python中正确地中断循环
目前我正试图通过API调用上传一组文件。这些文件具有顺序名称:part0.xml、part1.xml等。它循环所有文件并正确上载它们,但似乎没有中断循环,在它上载目录中最后一个可用文件后,我收到一个错误: 没有这样的文件或目录 我真的不明白如何在目录中的最后一个文件上传后立即停止。也许这是一个非常愚蠢的问题,但我真的迷路了。如何阻止它在不存在的文件中循环 守则:在Python中正确地中断循环,python,Python,目前我正试图通过API调用上传一组文件。这些文件具有顺序名称:part0.xml、part1.xml等。它循环所有文件并正确上载它们,但似乎没有中断循环,在它上载目录中最后一个可用文件后,我收到一个错误: 没有这样的文件或目录 我真的不明白如何在目录中的最后一个文件上传后立即停止。也许这是一个非常愚蠢的问题,但我真的迷路了。如何阻止它在不存在的文件中循环 守则: part = 0 with open('part%d.xml' % part, 'rb') as xml: #here go
part = 0
with open('part%d.xml' % part, 'rb') as xml:
#here goes the API call code
part +=1
我也试过这样的方法:
import glob
part = 0
for fname in glob.glob('*.xml'):
with open('part%d.xml' % part, 'rb') as xml:
#here goes the API call code
part += 1
import glob
for fname in glob.glob('part*[0-9].xml'):
with open(fname, 'rb') as xml:
#here goes the API call code
编辑:谢谢大家的回答,学到了很多。还有很多东西要学。:) 考虑如果有其他文件与
'*.xml'
假设您有11个文件“part0.xml”…“part10.xml”,但还有一个名为“foo.xml”的文件
然后for循环将迭代12次(因为glob有12个匹配项)。在第12次迭代中,您试图打开不存在的“part11.xml”
import os
from itertools import count
filenames = ('part%d.xml' % part_num for part_num in count())
for filename in filenames:
if os.path.exists(filename):
with open(filename, 'rb') as xmlfile:
do_stuff(xml_file)
# here goes the API call code
else:
break
另一种方法是转储glob并只处理异常
part = 0
while True:
try:
with open('part%d.xml' % part, 'rb') as xml:
#here goes the API call code
part += 1
except IOerror:
break
使用计数器时,需要测试文件是否存在:
import os
from itertools import count
for part in count():
filename = 'part%d.xml' % part
if not os.path.exists(filename):
break
with open(filename) as inp:
# do something
您的
for
循环是“对于以.xml
结尾的每个文件”;如果您有任何以.xml
结尾的文件不是顺序部分%d.xml
,您将得到一个错误。假设您有part0.xml
和foo.xml
。for
循环将循环两次;在第二个循环中,它将尝试打开不存在的part1.xml
import os
from itertools import count
filenames = ('part%d.xml' % part_num for part_num in count())
for filename in filenames:
if os.path.exists(filename):
with open(filename, 'rb') as xmlfile:
do_stuff(xml_file)
# here goes the API call code
else:
break
因为您已经知道文件名,所以甚至不需要使用glob.glob()
;只需在打开之前检查每个文件是否存在,直到找到一个不存在的文件
import os
from itertools import count
filenames = ('part%d.xml' % part_num for part_num in count())
for filename in filenames:
if os.path.exists(filename):
with open(filename, 'rb') as xmlfile:
do_stuff(xml_file)
# here goes the API call code
else:
break
如果出于任何原因,您担心文件会在
os.path.exists(文件名)
和open(文件名,'rb')
之间消失,那么这段代码会更加健壮:
import os
from itertools import count
filenames = ('part%d.xml' % part_num for part_num in count())
for filename in filenames:
try:
xmlfile = open(filename, 'rb')
except IOError:
break
else:
with xmlfile:
do_stuff(xmlfile)
# here goes the API call code
或者,您可以简单地使用正则表达式
import os, re
files = [f for f in os.listdir() if re.search(r'part[\d]+\.xml$', f)]
for f in files:
#process..
如果您需要高级过滤,这将非常有用
注意:您可以使用glob.glob()
如果您不熟悉列表理解和正则表达式,我建议您参考:
你差点就成功了。这是您的代码,删除了一些内容:
import glob
for fname in glob.glob('part*.xml'):
with open(fname, 'rb') as xml:
# here goes the API call code
可以使glob更加具体,但实际上它解决了“foo.xml”问题。关键是不要在Python中使用计数器;惯用的迭代是y中x的:
,您不需要计数器
glob
将按字母顺序返回文件名,因此您甚至不必担心这一点,但是请记住,['part1'、'part10'、'part2']按该顺序排序。有几种方法可以解决这个问题,但这是一个单独的问题。你做错了。
假设文件夹有3个文件——part0.xml part1.xml和foo.xml。所以循环将迭代3次,第三次迭代将给出错误,它将尝试打开part2.xml,但它不存在
不要循环浏览所有扩展名为.xml的文件
仅循环遍历以“part”开头的文件,扩展名前有一个数字,扩展名为.xml
因此,您的代码将如下所示:
import glob
part = 0
for fname in glob.glob('*.xml'):
with open('part%d.xml' % part, 'rb') as xml:
#here goes the API call code
part += 1
import glob
for fname in glob.glob('part*[0-9].xml'):
with open(fname, 'rb') as xml:
#here goes the API call code
读-
如果您希望按顺序上载文件,请阅读:您是否考虑过如果目录包含名为“foo.xml”的文件会发生什么情况?是的,我对其进行了测试,它只上载名称为('part%d.xml'%part')的文件。我不确定glob部分是否有必要。那么没有,您还没有考虑会发生什么。如果它包含“foo.xml”,会发生什么?当您似乎忽略了
fname
时,为什么要使用glob
?因此在第一个示例中,如果路径part5.xml存在,但有效用户无法打开文件,即使part6.xml到part12.xml没有问题,程序也应该停止而没有任何指示?第二个例子几乎以不同的方式做同样的事情。即使是cat
也能在无法打开文件时给你温暖,然后继续处理其余的文件。@msw,真正的代码必须处理的很多事情可能会出错;当然比你提到的要多。我只是回答一个问题:)。但当你吞咽错误时,你假装你在处理错误。现在又有一个人认为这是做事情的好方法。换句话说,循环终止的条件是错误的。