Frage

Ist es möglich, die zu verwenden? with Anweisung direkt mit CSV -Dateien? Es scheint natürlich, so etwas tun zu können:

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

Aber csv.reader liefert das nicht __enter__ und __exit__ Methoden, also funktioniert das nicht. Ich kann es jedoch in zwei Schritten tun:

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

Ist dieser zweite Weg der ideale Weg, dies zu tun? Warum sollten sie CSV.reader nicht direkt mit der With -Erklärung kompatibel machen?

War es hilfreich?

Lösung

Die primäre Verwendung von with Die Anweisung ist eine ausnahmslos sichere Reinigung eines in der Anweisung verwendeten Objekts. with stellt sicher, dass die Dateien geschlossen sind, Sperren veröffentlicht werden, Kontexte wiederhergestellt werden usw.

Tut csv.reader Haben Sie in Ausnahme die Dinge aufräumen?

Ich würde mit:

with open("myfile.csv") as f:
    for row in csv.reader(f):
        # process row

Sie müssen den Patch nicht einreichen, um sie zu verwenden csv.reader und with Aussage zusammen.

import contextlib

Hilfe bei Funktionskontextmanager im Modul Kontextlib:

contextmanager(func)
    @contextmanager decorator.

Typische Verwendung:

    @contextmanager
    def some_generator(<arguments>):
        <setup>
        try:
            yield <value>
        finally:
            <cleanup>

Dies macht das:

    with some_generator(<arguments>) as <variable>:
        <body>

entspricht dem:

    <setup>
    try:
        <variable> = <value>
        <body>
    finally:
        <cleanup>

Hier ist ein konkretes Beispiel, wie ich es verwendet habe: Flüche_Screen.

Andere Tipps

Ja. Der zweite Weg ist korrekt.

Warum? Wer weiß jemals. Sie haben Recht, es ist wahrscheinlich eine einfache Veränderung. Es ist nicht so hochrangig wie andere Dinge.

Sie können problemlos Ihr eigenes Patch -Kit erstellen und einreichen.

Das Problem ist, dass CSV.reader einen Kontext nicht wirklich verwaltet. Es kann iterable, nicht nur eine Datei akzeptieren. Daher ruft es seine Eingabe nicht in die Nähe des Eingangs (wenn es sich um contextlib.closing verwenden kann) nicht an. Es ist also nicht offensichtlich, welche Kontextunterstützung für CSV.reader tatsächlich tun würde.

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

Es ist einfach, das zu erstellen, was Sie mit einer Generatorfunktion möchten:


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
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top