2012-11-22 25 views
1

我有一個for循環,它貫穿一個目錄並處理那裏的文件,但我只想一次處理一定數量的文件。例如,我有一個包含1000個文件的目錄,但是我一天只能處理250個文件,所以當我第一次運行腳本時,它會處理前250個文件,然後處理250個文件,等等。FOR循環範圍一次處理特定數量的文件

首先,我正在檢查文件名是否與記錄已經同步的文件的名稱的XML文件相匹配,以便我不再處理它們。然後,我想處理下一個n個文件,在那裏我有一個變量synclimit = n

我想過範圍內聲明添加到for循環是這樣的:

tree = ET.parse("sync_list.xml") 
root = tree.getroot() 
synced = [elt.text for elt in root.findall('synced/sfile')] 
for filename in os.listdir(filepath) and in range (0, synclimit) : 
    if fnmatch.fnmatch(filename, '*.txt') and filename not in synced: 
    filename = os.path.join(filepath, filename) 
    result = plistlib.readPlist(filename) 

但是,我敢肯定這隻會每次檢查目錄中前n個文件。我應該將範圍語句添加到if語句中嗎?如:

tree = ET.parse("sync_list.xml") 
root = tree.getroot() 
synced = [elt.text for elt in root.findall('synced/sfile')] 
for filename in os.listdir(filepath): 
    if fnmatch.fnmatch(filename, '*.txt') and filename not in synced and in range (0, synclimit): 
    filename = os.path.join(filepath, filename) 
    result = plistlib.readPlist(filename) 

還是有更簡單的方法來做到這一點?謝謝。

回答

1

只要保留一個單獨的計數器並增加它,然後測試它是否已達到synclimit。就那麼簡單。沒有必要弄得太巧在這裏:

processed = 0 
for filename in os.listdir(filepath): 
    if not filename.endswith('.txt') or filename in synched: 
     continue 
    # process 
    processed += 1 
    if processed >= synclimit: 
     break # done for today. 

另外,由於os.listdir()返回一個列表,你可以過濾它,如果你有一組您已經同步的文件名列表,然後切片下來到你的最大尺寸:

synced = set(elt.text for elt in root.findall('synced/sfile')) 
to_process = [f for f in os.listdir(filepath) if f.endswith('.txt') and f not in synched] 

for filename in to_process[:synclimit]: 
    # process 

請注意,我只是測試.endswith('.txt')而不是用簡單的filematcher;測試歸結爲同樣的事情。

+0

兩者都比我想出的更優雅的解決方案。我唯一擔心的是被中斷的進程。我的腳本的最後一部分使用谷歌smtp電子郵件文件,這是臭名昭着的終止連接。我有一個帶有睡眠的while循環包裹的發送函數,所以如果失敗了,它應該再放3次才放棄。但有些時候我必須開始編寫腳本。所以我把XML保存爲今日的日期作爲文件名旁邊的屬性。然後我建立屬性=今天的元素的數量。然後,使用synclimit = 250 - syncedtoday動態構建synclimit。 – sosukeinu

+0

改爲使用適當的(本地)MTA。它會根據需要對您的電子郵件進行後臺處理,並在Google準備好時發送。 –

+0

關於如何實現這個的文檔?謝謝。 – sosukeinu