gpt4 book ai didi

python - 检查并关闭 python 生成器

转载 作者:行者123 更新时间:2023-11-28 17:40:50 25 4
gpt4 key购买 nike

我有一段代码使用生成器从两个大文件中读取,并在两个文件之一达到 EOF 时停止。我想知道(1)哪个生成器最先到达 EOF,(2)每个生成器的进度,即第一个生成器到达 EOF 时生成器中 i 的值(见下面的代码) ,以及 (3) 另一个生成器中剩余的行数。我事先不知道每个文件有多长,并且希望避免预先扫描文件。

我知道我可以通过以下方式获得进度:

  1. 每次我调用 next() 时增加一个计数器(这很丑陋!),或者

  2. 让生成器返回一个计数器(见代码中的counter1counter2),

但在这两种情况下,我都不知道 gen1gen2 中的哪一个达到了 EOF。

我还发现我可以向 StopIteration 异常添加“消息”,但我想知道是否有更好的方法。在第一个 try...except block 之后,我能否以某种方式找出哪个尚未达到 EOF 并推进它? (我尝试在生成器上使用 close()throw() ,或者生成器内部的 finally 子句,但并没有真正理解他们。)

def gen1(fp):
for i, line in enumerate(fp):
int_val = process_line(line)
yield int_val, i
raise StopIteration, ("gen1", i)

def gen2(fp):
for i, line in enumerate(fp):
float_val = process_line_some_other_way(line)
yield float_val, i
raise StopIteration, ("gen2", i)

g1 = gen1(open('large_file', 'r'))
g2 = gen2(open('another_large_file', 'r'))

try:
val1, counter1 = next(g1)
val2, counter2 = next(g2)
progress += 1
while True: # actual code is a bit more complicated than shown here
while val1 > val2:
val2, counter2 = next(g2)
while val1 < val2:
val1, counter1 = next(g1)
if val1 == val2:
do_something()
val1, counter1 = next(g1)
val2, counter2 = next(g2)

except StopIteration as err:
first_gen_name, first_num_lines = err.args

gen1_finished_first = gen_name == 'gen1'

# Go through the rest of the other generator to get the total number of lines
the_remaining_generator = g2 if gen1_finished_first else g1
try:
while True:
next(the_remaining_generator)
except StopIteration as err:
second_gen_name, second_num_lines = err.args

if gen1_finished_first:
print 'gen1 finished first, it had {} lines.'.format(first_num_lines) # same as `counter1`
print 'gen2 was at line {} when gen1 finished.'.format(counter2)
print 'gen2 had {} lines total.'.format(second_num_lines)
else:
... # omitted

最佳答案

我想你可能想使用 an iterator class相反——它是用标准的 Python 类实现的,并且可以具有您需要的任何额外属性(例如 exhausted 标志)。

类似下面的内容:

# untested
class file_iter():
def __init__(self, file_name):
self.file = open(file_name)
self.counted_lines = 0
self.exhausted = False
def __iter__(self):
return self
def __next__(self):
if self.exhausted:
raise StopIteration
try:
next_line = self.file.readline()
self.counted_lines += 1
return next_line
except EOFError:
self.file.close()
self.exhausted = True
raise StopIteration

关于python - 检查并关闭 python 生成器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24543482/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com