[英]Breaking the loop properly in Python
目前我正在尝试通过API调用上传一组文件。 这些文件有顺序名称:part0.xml,part1.xml等。它循环遍历所有文件并正确上传它们,但它似乎没有打破循环,并在它上传我目录中的最后一个可用文件后收到错误:
没有相应的文件和目录。
并且我真的不明白如何在目录中的最后一个文件上传后立即停止。 可能这是一个非常愚蠢的问题,但我真的迷路了。 如何阻止它循环遍历不存在的文件?
编码:
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 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中使用计数器; 惯用迭代是for x in y:
并且您不需要计数器。
glob
将按字母顺序返回文件名,因此您甚至不必担心,但请记住['part1','part10','part2']按此顺序排序。 有几种方法可以解决这个问题,但这将是一个单独的问题。
考虑如果有其他文件与'*.xml'
匹配会发生什么
假设您有11个文件“part0.xml”...“part10.xml”,但也有一个名为“foo.xml”的文件
然后for循环将迭代12次(因为glob有12个匹配)。 在第12次迭代中,您尝试打开不存在的“part11.xml”。
方法是转储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
结尾但不是顺序part%d.xml
,你将会收到一个错误。 想象一下,你有part0.xml
和foo.xml
。 for
循环将循环两次; 在第二个循环中,它将尝试打开不存在的part1.xml
。
既然你已经知道了文件名,你甚至不需要使用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(filename)
和open(filename, '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
你做错了。 假设文件夹有3个文件 - part0.xml part1.xml和foo.xml。 因此循环将迭代3次并且它将在第三次迭代时给出错误,它将尝试打开不存在的part2.xml。
不要遍历扩展名为.xml的所有文件。
只循环遍历以'part'开头的文件,在扩展名前面有一个数字,并且扩展名为.xml
所以你的代码看起来像这样:
import glob
for fname in glob.glob('part*[0-9].xml'):
with open(fname, 'rb') as xml:
#here goes the API call code
读取 - glob - 文件名模式匹配
如果您希望按顺序上传文件,请阅读: String Natural Sort
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.