21

withステートメントを CSV ファイルで直接使用することは可能ですか? 次のようなことができるのは当然のようです。

import csv
with csv.reader(open("myfile.csv")) as reader:
    # do things with reader

しかし csv.reader は__enter__and__exit__メソッドを提供していないため、これは機能しません。ただし、次の2つの手順で実行できます。

import csv
with open("myfile.csv") as f:
    reader = csv.reader(f)
    # do things with reader

この2番目の方法は理想的な方法ですか? csv.reader を with ステートメントと直接互換性を持たせないのはなぜですか?

4

5 に答える 5

21

ステートメントの主な用途は、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

于 2009-01-14T00:24:41.657 に答える
4

はい。2 番目の方法が正しいです。

なぜですか?誰が知っていますか。そうです、おそらく簡単な変更です。他のものほど優先度は高くありません。

独自のパッチ キットを簡単に作成して送信できます。

于 2009-01-13T22:45:20.360 に答える
2

問題は、 csv.reader が実際にはコンテキストを管理していないことです。ファイルだけでなく、あらゆるイテラブルを受け入れることができます。したがって、入力時に close を呼び出しません (ちなみに、呼び出した場合は contextlib.closing を使用できます)。そのため、 csv.reader のコンテキスト サポートが実際に何をするかは明らかではありません。

于 2009-01-14T04:57:06.507 に答える
1
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
于 2011-06-01T21:11:58.500 に答える
0

ジェネレーター関数を使用して、必要なものを簡単に作成できます。


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
于 2009-01-14T02:01:06.800 に答える