我已经阅读了很多类似的问题,但是他们中的大多数都是通过修复缩进来解决的,所以要么我无能为力,要么有一些简单的方法来解决我的问题,但我不认为这是关于身份的。
所以我有这个功能,基本上使用两个* .txt文件执行一些操作,并返回namedtuples
的生成器对象,其中包含我需要稍后查找的一些信息。
def master_reader(file1, file2):
with open(file1, "r", encoding="utf-8") as genomas:
with open(file2, "r", encoding="utf-8") as listas:
l = parser_listas(listas)
f = parser_genomas(genomas)
f = map(intifier, f)
f = (people_maker(linea, l) for linea in f)
f = map(genotipo_getter, f)
f = map(fen_getter, f)
return f
当我调用它并将其分配给变量时,事情就是一切正常。但是我需要将它用作参数,所以每次我需要它时我都可以调用它来执行我需要执行的一些查询:
print(valor_caracteristica("TCT", "Luna Lovegood", master_reader("genomas.txt", "listas.txt")))
但我得到了这个例外:
Original exception was:
Traceback (most recent call last):
File "lib.py", line 204, in <module>
print(valor_caracteristica("TCT", "Luna Lovegood", master_reader("genomas.txt", "listas.txt")))
File "lib.py", line 194, in valor_caracteristica
a = next(filter(lambda x: x.nombre == nombre, file))
File "lib.py", line 185, in <genexpr>
f = (people_maker(linea, l) for linea in f)
ValueError: I/O operation on closed file.
答案 0 :(得分:3)
map()
返回一个迭代器。只有当您遍历map()
对象时,它才会将该函数实际应用于输入可迭代的下一个元素。
因此,在您开始使用map
对象和基础生成器表达式之前,没有从您的文件中读取数据。您在函数外部执行此操作,并且该文件已在该时间关闭,因为return f
语句退出函数并扩展了上下文。
解决方法是要么不使用像map()
之类的惰性对象,要么使你的函数成为生成器函数。后者不会退出(并通知with
块以退出上下文),直到您完成该文件。
使用yield from
:
def master_reader(file1, file2):
with open(file1, "r", encoding="utf-8") as genomas:
with open(file2, "r", encoding="utf-8") as listas:
l = parser_listas(listas)
f = parser_genomas(genomas)
f = map(intifier, f)
f = (people_maker(linea, l) for linea in f)
f = map(genotipo_getter, f)
yield from map(fen_getter, f)
yield from
保持生成器处于打开状态,直到基础map()
对象引发StopIteration
。
快速演示来说明差异:
>>> from contextlib import contextmanager
>>> @contextmanager
... def democtx():
... print('Entering the context')
... yield
... print('Exiting the context')
...
>>> def return_map():
... with democtx():
... return map(lambda x: x**2, range(3))
...
>>> def yield_from_map():
... with democtx():
... yield from map(lambda x: x**2, range(3))
...
>>> example1 = return_map()
Entering the context
Exiting the context
>>> example2 = yield_from_map()
>>> next(example2)
Entering the context
0
>>> next(example2)
1
>>> next(example2)
4
>>> next(example2)
Exiting the context
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
注意example1
如何在返回时立即退出上下文,而example2
在迭代开始之前没有打开上下文,并且在我们完全遍历{{1}之前没有关闭上下文对象。
答案 1 :(得分:1)
由于您正在使用def get_value_idx(value):
model = QSqlTableModel()
model.setTable("pvalues")
model.setFilter("val = '%s'" % (value))
model.select()
count = model.rowCount()
if count >= 1:
l = list()
for n in range(count):
id = model.record(n).value('id')
l.append(id)
return l # return id list
if count == 0:
return -1 # return id that shows error
,Python 3
构造会返回生成器,这些生成器会被延迟评估。因此,当评估生成器map
时,文件处理程序已经关闭(打开文件的上下文管理器确保了这一点)。
解决方案是评估其中的地图,或者根本不使用它们,并使用列表理解。
f