“ with”を使用するPythonのCSVファイルのステートメント

StackOverflow https://stackoverflow.com/questions/441130

  •  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
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top