2014-05-05 36 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秒),则重置已查看/匹配的计数器。

相关问题