2012-09-29 58 views
1

被给了一些代码(我使用Python 3.2),并不断得到下面的错误。Python - 字符串错误

import csv 
import collections 
import itertools 

grid = collections.Counter() 

with open("test1.csv", "r") as fp: 
reader = csv.reader(fp) 
for line in reader: 
    for pair in itertools.combinations(line, 2): 
     grid[pair] += 1 
     grid[pair[::-1]] += 1 

actors = sorted(set(pair[0] for pair in grid)) 

with open("connection_grid.csv", "wb") as csvfile: 
    writer = csv.writer(fp) 
    writer.writerow([''] + actors) 
    for actor in actors: 
     line = [actor,] + [grid[actor, other] for other in actors] 
     writer.writerow(line) 

但我得到这个错误。

Traceback (most recent call last): File "C:/Python32/test.py", line 21, in writer.writerow([''] + actors) ValueError: I/O operation on closed file.

+0

您编辑了第二个'with'以使用'作为csvfile',但'writer'仍尝试引用'fp'。这是行不通的。 – DSM

+0

'作家= csv.writer(fp)'在这行代替fp与csvfile –

+0

伙计们,那些是答案,不是评论。 – yak

回答

3

如果b是在模式则文件以二进制模式,而不是文本模式打开。去掉它。

+0

这非常有帮助!不过,现在我得到的错误: '回溯(最近通话最后一个):文件 “C:/Python32/test.py”,第21行,在 writer.writerow([''] +演员) ValueError异常:我/ O操作关闭的文件。'我已经用你的修复和新的错误更新了这个问题。 – FJ17

+2

不要这样做。打开一个新问题。 –

0

问题是你指的是错误的变量。早期,您创建了一个文件对象fp,稍后您将创建csvwriter。在第二部分中,您应该写信给csvwriter,但是您可以写信给fp。例外情况是告诉你fp已经关闭,当你从with块开始缩进时会发生这种情况。

第一嵌段是细:

with open("test1.csv", "r") as fp: 
    reader = csv.reader(fp) 
    ... 

注意,第二块仍是指fp

with open("connection_grid.csv", "wb") as csvfile: 
    writer = csv.writer(fp) 
    ... 
+0

尽管如此,代码仍然无法工作。 OP使用3.2,所以'open'需要用'newline ='''调用。 – DSM

+0

由于遇到的异常来自于关闭的文件,我将保持原样。 –

0

csv模块的医生说来open(fname, 'rb')'wb' - 即在二进制模式下。但是这只适用于Python 2.x.

在Python 3中,CSV文件必须以普通文本模式打开。但是,仍然必须做一些特别的事情。该医生说(见http://docs.python.org/release/3.2.3/library/csv.html#csv.reader):

If csvfile is a file object, it should be opened with newline='' .

所以,正确的做法是:

with open("test1.csv", newline='') as fp: 
    reader = csv.reader(fp) 
    ... 
... 
with open("connection_grid.csv", "w", newline='') as csvfile: 
    writer = csv.writer(csvfile) 
    ... 

Ohterwise,蒂姆已经指出你错误地传递了错误的文件对象的作家。正因为如此,给变量赋予真正的描述性名称会更好。当你给文件对象变量而不是文件名变量时,它也有帮助。

而且因为代码的未来改进的,它可能是好主意,首先指定文件名的变量。然后,它是便于以后的代码块转换为函数体,这样的:

def csv_transformation(csvname_in, csvname_out): 
    with open(csvname_in, newline='') as finput: 
     reader = csv.reader(finput) 
     ... 
    ... 
    with open(csvname_out, 'w', newline='') as foutput: 
     writer = csv.writer(foutput) 
     ... 

在这种情况下,更难以犯的错误。