2015-10-15 9 views
5

Sto provando a sottoclasse io.TextIOWrapper dopo il this post, anche se i miei obiettivi sono diversi. Partendo con questo (NB: motivation):File di sottoclassi per sottoclasse `io.TextIOWrapper` - ma quale firma ha il suo costruttore?

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

Sto cercando di aprire un file usando il mio costruttore utilizzando

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

ma questo dà:

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

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

E, in effetti, sembra che il costruttore di io.TextIOWrapper si aspetti che passi un oggetto file. Attraverso tentativi ed errori, ho scoperto che questo oggetto file deve essere aperto nella modalità binaria. Ma non riesco a trovare la documentazione da nessuna parte, e non ho voglia di costruire un comportamento non documentato (anzi, un tentativo di andare avanti mi porta già a dei problemi quando provo a passare il mio oggetto a csv.reader). Qual è il modo corretto e supportato per creare una sottoclasse di un oggetto file in Python 3?

Sto usando Python 3.5.0.

+2

Considerare l'uso della composizione; chiedi alla tua classe di usare 'open' per aprire il file e salvare invece un riferimento all'oggetto restituito. – chepner

+0

@chepner Non sono sicuro di cosa intendi esattamente: intendi non ereditare dalla famiglia 'io.IOBase'? In definitiva, voglio passare questo a 'csv.csvreader' e quindi il mio scopo è quello di leggere il file spogliato di tutti i NUL (vedi [questa domanda] (http://stackoverflow.com/a/4169762/974555)). – gerrit

+0

Diritto; 'csv.csvreader' non si cura del tipo che riceve, purché implementa il protocollo iteratore (cioè, ha un metodo' next' che può essere chiamato per ottenere la riga successiva). – chepner

risposta

2

penso che la documentazione che si sta cercando è

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

il primo argomento è un flusso binario, il che implica qualcosa di aperto in modo binario per open.

0

Per quanto riguarda il "fissare" il file CSV, si potrebbe anche usare un generatore:

# 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() 

Ma il problema è probabilmente causato da un file UTF-16 codificato.

+0

Non è codificato utf-16. Non conosco la codifica. È un CSV generato da Surveymonkey. Ma questa è una domanda diversa (mi rendo conto che la mia domanda è in qualche modo un problema XY). – gerrit

Problemi correlati