下面的简单代码包含一些I / O操作。我在关闭文件错误时遇到 I / O操作,并想知道我做错了什么以及如何修复它。
def externalSortStream(iterator, partId=0, reverse=False, keyfunc=None, serial=serializer, limit=10, batch=100):
"""
Given an iterator, returns an iterator of sorted elements (according to parameters).
:param iterator: iterator. Expects (Key, Value).
:param keyfunc: function applied on the keykey.
:param reverse: Reverse default ordering if true. (default is ascending; reverse is descending)
:param serializer: See README.
:param limit: memory limit.
:param batch: Number of elements to read at a time.
"""
all_runs = [] # can be used to hold a list of iterators
run = [] # used to hold the current run of elements
def load(fileobj):
"""
Returns a generator object that outputs elements
from a serialized (saved) stream. Closes the file when done.
:param fileobj: python object file
"""
for _ in serial.load_stream(fileobj):
yield _
fileobj.close()
# TODO everywhere below
n = 0
fileList = []
while True:
c = list(itertools.islice(iterator, batch))
run += c
# TODO
if len(c) != batch:
#last group
run = sorted(run, key = lambda ele: ele[0])
filename = get_sort_dir(partId, n)
fileList.append(filename)
with open(filename, "w+") as writeFile:
serializer.dump_stream(run, writeFile)
break
if get_used_memory() > limit: # TODO
run = sorted(run, key = lambda ele: ele[0])
filename = get_sort_dir(partId, n)
fileList.append(filename)
with open(filename, "w+") as writeFile:
serializer.dump_stream(run, writeFile)
n += 1
run = []
# TODO some cleanup stuff
for fi in fileList:
#for each file, open, close, then delete
with open(fi, "r") as current:
all_runs.append(load(current))
os.unlink(fi)
return heapq.merge(all_runs, key=lambda x: keyfunc(x[0]), reverse=reverse)
完整追溯:
ValueError
Traceback (most recent call last)
<ipython-input-18-4e28c39b6fbb> in <module>()
1 test_stream = ((i, i) for i in range(100))
----> 2 list(externalSortStream(test_stream, keyfunc=(lambda x: abs(50 - (x ** 2)))))[:10]
heapq3.py in merge(iterables, key, reverse)
651 for order, it in enumerate(map(iter, iterables)):
652 try:
--> 653 value = next(it)
654 h_append([key(value), order * direction, value, it])
655 except StopIteration:
<ipython-input-15-ec61ab2b349c> in load(fileobj)
21 :param fileobj: python object file
22 """
---> 23 for _ in serial.load_stream(fileobj):
24 yield _
25 fileobj.close()
serializers.py in load_stream(self, stream)
137 while True:
138 try:
--> 139 yield self._read_with_length(stream)
140 except EOFError:
141 return
serializers.py in _read_with_length(self, stream)
154
155 def _read_with_length(self, stream):
--> 156 length = read_int(stream)
157 if length == SpecialLengths.END_OF_DATA_SECTION:
158 raise EOFError
serializers.py in read_int(stream)
541
542 def read_int(stream):
--> 543 length = stream.read(4)
544 if not length:
545 raise EOFError
ValueError: I/O operation on closed file
答案 0 :(得分:0)
第4行至最后一行:
with open(fi, "r") as current:
需要更改为:
current = open(fi, "r")
就是这样。这解决了我的问题。 load()关闭当前,显然我无法关闭中的当前与当前的open()as ... 代码段强>