2016-04-18 6 views
2

Мой код (упрощенно):python - Запись в файл csv из раковины coroutine ... как избежать закрытой ошибки файла?

import csv 


def generate_record(downstream): 
    try: 
     while True: 
      incoming = (yield) 
      record = incoming.strip() 
      for worker in downstream: 
       worker.send(record) 
    except GeneratorExit: 
     for worker in downstream: 
      worker.close() 
     print('generate_record shutdown') 


def file_writer(filename): 
    l = list()  
    try: 
     while True: 
      record = (yield) 
      l.append(record) 
    except GeneratorExit: 
     with open(filename, 'w', newline=''): 
      writer = csv.writer(f) 
      writer.writerows(l) 
     print('file_writer shutdown') 


if __name__ == '__main__': 
    sink = file_writer('C:/Users/Some User/Downloads/data.csv') 
    next(sink)  
    worker = generate_record([sink]) 
    next(worker) 
    with open('C:/Users/Some User/Downloads/Energy.txt') as f: 
     for line in f: 
      worker.send(line) 
    worker.close() 

Формирует следующее сообщение об ошибке:

Traceback (most recent call last): 

    File "<ipython-input-43-ff97472f6399>", line 1, in <module> 
    runfile('C:/Users/Some User/Documents/Python Scripts/isii.py', wdir='C:/Users/Some User/Documents/Python Scripts') 

    File "C:\Users\Some User\Anaconda3\lib\site-packages\spyderlib\widgets\externalshell\sitecustomize.py", line 699, in runfile 
    execfile(filename, namespace) 

    File "C:\Users\Some User\Anaconda3\lib\site-packages\spyderlib\widgets\externalshell\sitecustomize.py", line 88, in execfile 
    exec(compile(open(filename, 'rb').read(), filename, 'exec'), namespace) 

    File "C:/Users/Some User/Documents/Python Scripts/isii.py", line 75, in <module> 
    worker.close() 

    File "C:/Users/Some User/Documents/Python Scripts/isii.py", line 49, in generate_record 
    worker.close() 

    File "C:/Users/Some User/Documents/Python Scripts/isii.py", line 63, in file_writer 
    writer.writerows(l) 

ValueError: I/O operation on closed file. 

Что я пробовал?

Я пытался постепенно писать с writerow в file_writer в try блоке, но это порождает ту же ошибку.

+1

'worker.send (output)' похоже, опечатка 'worker.send (record)'. – falsetru

ответ

3

with заявление в file_writer отсутствует as f part; по ошибке, f ссылается на глобальную переменную f, которая закрыта на момент написания; случаев IOError.

with open(filename, 'w', newline='') as f: 
            ^^^^ 
0

Когда вы используете with open(filename) as f:, он выполнит операцию, которую вы добавили, а затем закроет файл. Поэтому вам не нужно использовать worker.close(), так как вы пытаетесь закрыть файл, который уже закрыт.

См: What is the python keyword "with" used for?

Это должно быть комментарий, но я, кажется, не хватает репутации для этого.

+0

Вы все равно должны закрыть сопрограмму. Без этого окончательного работника. Coroutine остается открытым. – MikeRand