在Python中使用CSV文件的“ WANT”语句
-
22-07-2019 - |
题
是否可以使用 with
直接使用CSV文件进行声明?能够做这样的事情似乎很自然:
import csv
with csv.reader(open("myfile.csv")) as reader:
# do things with reader
但是csv.Reader不提供 __enter__
和 __exit__
方法,因此这不起作用。但是,我可以通过两个步骤进行操作:
import csv
with open("myfile.csv") as f:
reader = csv.reader(f)
# do things with reader
第二种方式是理想的方法吗?他们为什么不使csv.Reader直接与with语句兼容?
解决方案
主要用途 with
语句是对语句中使用的对象的例外安全清理。 with
确保文件关闭,释放锁,恢复上下文,等等。
做 csv.reader 如果有例外,请清理工作吗?
我会选择:
with open("myfile.csv") as f:
for row in csv.reader(f):
# process row
您无需提交补丁即可使用 csv.reader
和 with
一起声明。
import contextlib
在模块中帮助函数上下文manager contextlib:
contextmanager(func)
@contextmanager decorator.
典型用法:
@contextmanager
def some_generator(<arguments>):
<setup>
try:
yield <value>
finally:
<cleanup>
这使得:
with some_generator(<arguments>) as <variable>:
<body>
等效于此:
<setup>
try:
<variable> = <value>
<body>
finally:
<cleanup>
这是我如何使用它的具体示例: Curses_screen.
其他提示
是的。第二种方式是正确的。
至于为什么?谁知道。您是对的,这可能是一个容易的变化。它不如其他事情那么优先。
您可以轻松地制作自己的补丁套件并提交。
问题是csv.Reader并没有真正管理上下文。它可以接受任何可观的,而不仅仅是文件。因此,它不会在其输入上关闭(顺便说一句,如果您可以使用ContextLib.Closing)。因此,对于CSV.Reader实际上会有哪些上下文支持并不明显。
import csv
class CSV(object):
def __init__(self,path,mode):
self.path = path
self.mode = mode
self.file = None
def __enter__(self):
self.file = open(self.path,self.mode)
if self.mode == 'r':
return csv.reader(self.file)
elif self.mode == 'w':
return csv.writer(self.file)
def __exit__(self, exc_type, exc_val, exc_tb):
self.file.close()
with CSV('data.csv','r') as reader:
for row in reader:
print row
使用生成器函数很容易创建想要的东西:
import csv
from contextlib import contextmanager
@contextmanager
def opencsv(path):
yield csv.reader(open(path))
with opencsv("myfile.csv") as reader:
# do stuff with your csvreader
不隶属于 StackOverflow