【问题标题】:ValueError: I/O operation on closed (csv) fileValueError:对已关闭 (csv) 文件的 I/O 操作
【发布时间】:2018-05-05 01:31:57
【问题描述】:

我收到此错误:

Traceback (most recent call last):
  File "so.py", line 7, in <module>
    for review in x:
ValueError: I/O operation on closed file.

代码:

def get_reviews(path):
    with open(path, 'r', encoding = "utf-8") as file1:
        reviews = map(lambda x: x.strip().split(','), file1)
        return reviews

x = get_reviews("reviews.csv")
for review in x:
    print(review)

【问题讨论】:

  • 错误发生在哪一行?
  • 顺便说一句,您应该使用csv.reader 来读取 CSV 文件,您的代码无法正确处理引用和转义。
  • 欢迎来到 StackOverflow。请按照您创建此帐户时的建议阅读并遵循帮助文档中的发布指南。 Minimal, complete, verifiable example 适用于此。在您发布 MCVE 代码并准确描述问题之前,我们无法有效地帮助您。我们应该能够将您发布的代码粘贴到文本文件中并重现您描述的问题。
  • get_reviews() 返回的是一个生成器,直到for review in x: 语句才会执行,但是到那时文件已经关闭,因为with 已经关闭file1
  • 错误发生在第 7 行

标签: python python-3.x


【解决方案1】:

在 Python 3 中,map() 函数不会完全处理输入对象,而只是返回一个迭代器。因此,在您的 for 循环调用每一行之前,该文件实际上并没有得到处理。但是到那时,文件已经关闭,因为您的代码离开了 with 块。

这里有两个选择。首先,你可以让调用者传入一个打开的文件,并让他们处理打开和关闭文件:

def get_reviews(rev_file):
    return map(lambda x: x.strip().split(','), rev_file)

with open(path) as file1:
    for review in get_reviews(file1):
        print(review)

或者让get_reviews() 完全处理文件,比如返回一个列表。

def get_reviews(path):
    with open(path, 'r', encoding = "utf-8") as file1:
        return list(map(lambda x: x.strip().split(','), file1))

# alternate version using a list comprehension instead of map()
def get_reviews(path):
    with open(path, 'r', encoding = "utf-8") as file1:
       return [x.strip().split(',') for x in file1]

【讨论】:

    【解决方案2】:
    reviews = map(lambda x: x.strip().split(','), 
                 [_ for _ in file1] )
    

    您在文件对象上返回了一个生成器。当您将 with 块留在函数中时,该文件已关闭。

    【讨论】:

      猜你喜欢
      • 2018-12-18
      • 2013-09-27
      • 2016-07-21
      • 2015-07-20
      • 1970-01-01
      • 2016-08-26
      • 2016-06-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多