2015-10-15 4 views
5

Ich versuche, io.TextIOWrapper nach this post Unterklasse, obwohl meine Ziele anders sind. Beginnend mit diesem (NB: motivation):Subclassing-Datei durch Unterklasse "io.TextIOWrapper" - aber welche Signatur hat ihr Konstruktor?

class MyTextIOFile(io.TextIOWrapper): 
    def read(self, *args): 
     cont = super().read(*args) 
     return cont.replace("\x00", "") 

Ich versuche, eine Datei mit meinem Konstruktor zu öffnen mit

In [81]: f = MyTextIOFile("file.csv") 

aber das gibt:

--------------------------------------------------------------------------- 
AttributeError       Traceback (most recent call last) 
<ipython-input-90-343e18b2e32f> in <module>() 
----> 1 f = MyTextIOFile("file.csv") 

AttributeError: 'str' object has no attribute 'readable' 

Und in der Tat, Es scheint io.TextIOWrapper s Konstruktor erwartet, ein Dateiobjekt übergeben werden. Durch Versuch und Irrtum entdeckte ich, dass dieses Dateiobjekt in binär Modus geöffnet werden muss. Aber ich kann nirgendwo Dokumentationen finden, und ich habe nicht das Gefühl, auf undokumentiertem Verhalten aufzubauen (tatsächlich führt mich ein Versuch, damit fortzufahren, bereits zu Problemen, wenn ich versuche, mein Objekt an csv.reader zu übergeben). Was ist die korrekte und unterstützte Möglichkeit, ein Dateiobjekt in Python 3 zu unterklassifizieren?

Ich benutze Python 3.5.0.

+2

Verwenden Sie stattdessen die Komposition; Lassen Sie Ihre Klasse 'open' verwenden, um die Datei zu öffnen und einen Verweis auf das zurückgegebene Objekt zu speichern. – chepner

+0

@chepner Ich bin mir nicht sicher, was du genau meinst - meinst du nicht von der Familie "io.IObase" zu erben? Letztendlich möchte ich das an 'csv.csvreader' weitergeben und mein Ziel ist es daher, die Datei zu lesen, in der alle NULs gelöscht wurden (siehe [diese Frage] (http://stackoverflow.com/a/4169762/974555)). – gerrit

+0

Rechts; 'csv.csvreader' ist es egal, welchen Typ es empfängt, solange es das Iteratorprotokoll implementiert (d. h. es hat eine' nächste' Methode, die aufgerufen werden kann, um die nächste Zeile zu erhalten). – chepner

Antwort

2

Ich denke, die Dokumentation von Ihnen gesuchte ist

class io.TextIOWrapper(buffer, encoding=None, errors=None, newline=None, line_buffering=False) 
    A buffered text stream over a BufferedIOBase binary stream. [...] 

Das erste Argument ist ein binärer Strom, der durch open etwas geöffnet im Binär-Modus impliziert.

0

Soweit „Fixierung“ die CSV-Datei, können Sie auch einen Generator verwenden:

# untested 
def FixCsv(csv_file, *args, **kwds): 
    "assumes text-mode file; removes NUL-bytes" 
    if isinstance(csv_file, str): 
     file_obj = open(csv_file, *args, **kwds) 
    else: 
     file_obj = csv_file 
    for line in file_obj: 
     yield line.replace('\x00','') 
    file_obj.close() 

Aber dein Problem wahrscheinlich durch eine UTF-16-codierte Datei verursacht wird.

+0

Es ist nicht utf-16 codiert. Ich kenne die Codierung nicht. Es ist eine CSV von Surveymonkey generiert. Aber das ist eine andere Frage (ich weiß, dass meine Frage ein XY-Problem ist). – gerrit

Verwandte Themen