“ with”を使用するPythonのCSVファイルのステートメント
-
22-07-2019 - |
質問
CSVファイルで with
ステートメントを直接使用することはできますか?このようなことができるのは自然なことのようです:
import csv
with csv.reader(open("myfile.csv")) as reader:
# do things with reader
ただし、csv.readerは __ enter __
および __ exit __
メソッドを提供しないため、これは機能しません。ただし、2つの手順で実行できます。
import csv
with open("myfile.csv") as f:
reader = csv.reader(f)
# do things with reader
この2番目の方法は理想的な方法ですか? 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
モジュール contextlib の関数contextmanagerのヘルプ:
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 。
他のヒント
はい。 2番目の方法は正しいです。
理由は?誰が知っている。あなたは正しい、それはおそらく簡単な変更です。他のものほど優先順位は高くありません。
独自のパッチキットを簡単に作成して送信できます。
問題は、csv.readerが実際にコンテキストを管理していないことです。ファイルだけでなく、反復可能なものを受け入れることができます。したがって、入力でcloseを呼び出しません(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