2014-05-05 42 views
0

我遇到了一個問題,在這個問題中我使用python生成器處理來自文件的文檔。我需要處理的文件數量未預先知道。每個文件都包含消耗大量內存的記錄。因此,發電機用於處理記錄。這是我工作的代碼摘要:跟蹤我們在生成器中處理多少個元素

 
def process_all_records(files): 
    for f in files: 
     fd = open(f,'r') 
     recs = read_records(fd) 
     recs_p = (process_records(r) for r in recs) 
     write_records(recs_p) 

我process_records功能檢查每個記錄的內容,只返回具有特定發件人的記錄。我的問題如下:我想對read_records返回的元素數進行計數。我一直在使用一個列表跟蹤的記錄數的process_records功能:

 
def process_records(r): 
    if r.sender('sender_of_interest'): 
     records_list.append(1) 
    else: 
     records_list.append(0) 
    ... 

這種方法的問題是,records_list可以不依賴於輸入式增長。我希望能夠消耗records_list的內容,一旦它增長到某個點,然後重新啓動該過程。例如,在處理了20條記錄之後,我想知道'sender_of_interest'有多少條記錄以及其他來源有多少條記錄,並清空了這個記錄。我可以不使用鎖嗎?

+2

爲什麼不使用整數計數器而不是列表? – dano

+0

好像你可以讓'read_records()'檢查'sender'並且只返回那些感興趣的東西。在這種情況下,您分配給'recs'的價值回報的長度將是生成器將處理的數量。 – martineau

+0

是的,我可以。但我更喜歡你使用課堂的想法。我正在使用的代碼是由其他人編寫的,我寧願不要爲了我的目的而重構此代碼。謝謝。 –

回答

1

您可以使您的生成器具有一個屬性,該屬性包含已處理記錄的編號的計數。類似這樣的:

class RecordProcessor(object): 
    def __init__(self, recs): 
     self.recs = recs 
     self.processed_rec_count = 0 
    def __call__(self): 
     for r in self.recs: 
      if r.sender('sender_of_interest'): 
       self.processed_rec_count += 1 
       # process record r... 
       yield r # processed record 

def process_all_records(files): 
    for f in files: 
     fd = open(f,'r') 
     recs_p = RecordProcessor(read_records(fd)) 
     write_records(recs_p) 
     print 'records processed:', recs_p.processed_rec_count 
1

這是直接的方法。有什麼理由說明爲什麼這種簡單的東西不適合你?

seen=0 
matched=0 

def process_records(r): 
    seen = seen + 1 
    if r.sender('sender_of_interest'): 
     matched = match + 1 
     records_list.append(1) 
    else: 
     records_list.append(0) 

    if seen > 1000 or someOtherTimeBasedCriteria: 
     print "%d of %d total records had the sender of interest" % (matched, seen) 
     seen = 0 
     matched = 0 

如果你必須關閉的消息和數據流的能力重新打開它們,你可能需要一個更多的總看到變量,因此,如果您不得不關閉該流並隨後重新打開它,你可以轉到您處理的最後一個記錄並在那裏接收。

在此代碼中,「someOtherTimeBasedCriteria」可能是一個時間戳。開始處理時,您可以以毫秒爲單位獲取當前時間,然後如果當前時間現在超過20,000ms(20秒),則重置已查看/匹配的計數器。

相關問題