在Python中正确地打破循环

时间:2015-08-31 04:07:35

标签: 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

编辑:谢谢大家的答案,了解了很多。还有很多要学的东西。 :)

6 个答案:

答案 0 :(得分:2)

或者,您可以简单地使用正则表达式。

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()

返回的列表进行类似的过滤

如果您不熟悉列表理解和正则表达式,我建议您参考:

  1. Regex - howto
  2. List Comprehensions

答案 1 :(得分:2)

你几乎拥有它。这是删除了一些内容的代码:

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']按此顺序排序。有几种方法可以解决这个问题,但这将是一个单独的问题。

答案 2 :(得分:1)

如果有其他文件与'*.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

答案 3 :(得分:1)

使用计数器时,如果文件存在,则需要测试:

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

答案 4 :(得分:1)

您的for循环说“对于以.xml结尾的每个文件”;如果您有任何以.xml结尾的文件不是顺序part%d.xml,那么您将收到错误消息。想象一下,您有part0.xmlfoo.xmlfor循环将循环两次;在第二个循环中,它将尝试打开不存在的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

答案 5 :(得分:1)

你做错了。 假设文件夹有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 – Filename pattern matching

如果您希望按顺序上传文件,请阅读:String Natural Sort