[英]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.