2015-10-15 7 views
5

Я пытаюсь подкласса io.TextIOWrapper после this post, хотя мои цели разные. Начав с этого (NB: motivation):Подклассификация файла путем подкласса `io.TextIOWrapper` - но какая подпись имеет его конструктор?

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

Я пытаюсь открыть файл, используя свой конструктор, используя

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

, но это дает:

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

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

И действительно, io.TextIOWrapper s конструктор ожидает передачи файлового объекта. Через пробную версию и ошибку я обнаружил, что этот файл должен быть открыт в двоичном режиме. Но я не могу найти документацию нигде, и мне не хочется строить поверх недокументированного поведения (действительно, одна попытка продолжить это уже приводит к проблемам при попытке передать мой объект csv.reader). Каков правильный и поддерживаемый способ подкласса файлового объекта в Python 3?

Я использую Python 3.5.0.

+2

Рассмотрите возможность использования композиции; попросите свой класс использовать 'open', чтобы открыть файл и сохранить ссылку на возвращенный объект. – chepner

+0

@chepner Я не уверен, что вы имеете в виду - вы имеете в виду не наследование от семьи 'io.IOBase'? В конечном итоге я хочу передать это 'csv.csvreader', поэтому моя цель - прочитать файл, лишенный всех NUL (см. [Этот вопрос] (http://stackoverflow.com/a/4169762/974555)). – gerrit

+0

Право; 'csv.csvreader' не заботится о том, какой тип он получает, если он реализует протокол итератора (т. е. имеет следующий метод, который можно вызвать для получения следующей строки). – chepner

ответ

2

Я думаю, что документация вы ищете

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

Первый аргумент представляет собой бинарный поток, который подразумевает что-то открыт в двоичном режиме, open.

0

Что касается «фиксации» ваш файл CSV, вы можете также использовать генератор:

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

Но ваша проблема, вероятно, вызвана UTF-16 кодированный файл.

+0

Это не кодировка utf-16. Я не знаю кодировки. Это CSV, созданный Surveymonkey. Но это другой вопрос (я понимаю, что мой вопрос - это проблема XY). – gerrit