提问人:invalid syntax 提问时间:10/30/2023 最后编辑:invalid syntax 更新时间:10/30/2023 访问量:66
在不关闭文件的情况下调用新函数
call a new function without closing the file
问:
我有一个打开 csv 文件的方法和另一个我想用来处理这个文件的方法 - 但我也需要它来处理不同类型的对象,所以我想将其保留为一个独立的方法。
import csv
class Loader():
def load_from_csv(self, csv_path: str):
with open(csv_path, mode='r', encoding='utf-8') as file:
reader = csv.DictReader(file)
return self._read_and_yield(reader)
@classmethod
def _read_and_yield(cls,reader):
for row in reader:
yield(row)
loader = Loader()
for row in loader.load_from_csv('sample.csv'):
print(row)
但是我明白了,因为当我调用该方法时,文件似乎被关闭了。在这里,它只产生行,但想象一下我必须执行更多操作的情况:我应该对每种类型的文件(即 )重复此过程。ValueError: I/O operation on closed file
_read_and_yield
read_from_excel
我应该如何处理?
答:
1赞
blhsing
10/30/2023
#1
当封闭函数返回时,该模块将关闭文件,因此迭代器无法再从文件中读取。with
csv.DictReader
相反,您可以从上下文管理器中生成生成的值,以便在调用方对其进行迭代时文件句柄可以保持打开状态:load_from_csv
_read_and_yield
with open(csv_path, mode='r', encoding='utf-8') as file:
reader = csv.DictReader(file)
yield from self._read_and_yield(reader)
1赞
Codist
10/30/2023
#2
您可以考虑将 Loader 类重写为上下文管理器。
像这样的东西:
from csv import DictReader
class Loader:
def __init__(self, filename):
self._filename = filename
def __enter__(self):
self._fd = open(self._filename, "r", encoding="utf-8", newline="")
return self
def __exit__(self, *_):
self._fd.close() #type: ignore
def row(self):
yield from DictReader(self._fd) #type: ignore
with Loader("foo.csv") as loader:
for r in loader.row():
print(r)
评论
_read_and_yield()
self
with
load_from_csv()
load_from_csv()
yield
with
_read_and_yield
return
with
with
open
close
@staticmethod
@classmethod