簡體   English   中英

在Python中正確地打破循環

[英]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()返回的列表進行類似的過濾

如果您不熟悉列表理解和正則表達式,我建議您參考:

  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']按此順序排序。 有幾種方法可以解決這個問題,但這將是一個單獨的問題。

考慮如果有其他文件與'*.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.xmlfoo.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM