2016-04-18 14 views
2

我的代碼(簡化):python - 從協程接收器寫入csv文件...如何避免關閉的文件錯誤?

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. 

我有什麼企圖?

我試過在try塊內內writerow增量寫入,但會產生相同的錯誤。

+1

'worker.send(output)'似乎是'worker.send(record)'的拼寫錯誤。 – falsetru

回答

3

with陳述中的file_writer缺失as f部分;由於錯過了,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

儘管如此,您仍然必須關閉協程。沒有最終的worker.close,協程就保持打開狀態。 – MikeRand