2017-01-19 2 views
2

В современных версиях Ppython можно провести анализ статического типа с использованием аннотаций функций в соответствии с PEP 484. Это облегчается с помощью модуля ввода.Правильный способ аннотировать «тип файла» в Python

Теперь мне интересно, как бы я дал «тип намека» на «filestream».

def myfunction(file: FILETYPE): 
    pass 

with open(fname) as file: 
    myfunction(file) 

Что бы вставить как FILETYPE?

Использование print(type(file)) возвращает <class '_io.TextIOWrapper'>, что совсем неясно.

Не существует ли общий тип файлов?

+0

Нужно ли аннотацию ссылаться на физический файл на диске, или же он может включать в себя такие же файловые объекты, как 'StringIO'? – jwodder

ответ

1

Я думаю, что вы хотите io.IOBase, «[t] он абстрактный базовый класс для всех классов ввода-вывода, действующий на потоки байтов».

Обратите внимание, что это включает также потоки в памяти, такие как io.StringIO и io.BytesIO. Прочтите документацию по адресу module io.

+0

Как комментарий: хотя это «лучший» ответ, который я могу получить. Проблема по-прежнему не решена с этим. Многое зависит от _io._base и производных от этого. Нет никакого «общего» верхнего слоя для «_io._base» и «io.base»? – paul23

+0

@ paul23 Я не понимаю, что вы имеете в виду. AFAIK 'io.IOBase' - это лучший тип намека на« байтовый поток », и каждый файл-подобный объект, который может быть создан с использованием стандартной библиотеки, является его экземпляром. Если 'IOBase' не соответствует вашей идее байтового потока, или у вас есть прецедент, где это не очень хороший намек, вы можете отредактировать свой вопрос и объяснить, почему. – Goyo

+0

, например, если вы открываете поток байтов в байтах с BytesIO; Это происходит от '_BufferedIOBase', который происходит от' _IOBase' – paul23

3

Вы можете использовать typing.IO, typing.TextIO и typing.BinaryIO для представления различных типов потоков ввода-вывода. Цитирую documentation:

класса печатать. И.О.

        Упаковочный пространство имен для типов потоков ввода/вывода.

        Это определяет общий тип IO[AnyStr] и псевдонимы TextIO и BinaryIO для
        соответственно IO[str] и IO[bytes]. Они представляют собой типы потоков ввода-вывода , таких как
        как получено open().

        Эти типы также доступны непосредственно в typing.IO, typing.TextIO и
        typing.BinaryIO.

0

Либо это:

from typing import TextIO # or IO or BinaryIO 

def myfunction(file: TextIO): 
    pass 

ИЛИ это

from typing import TYPE_CHECKING 
if TYPE_CHECKING: 
    from typing import TextIO # or IO or BinaryIO 

def myfunction(file: 'TextIO'): 
    pass 

Второй подход позволит избежать импортировать класс во время выполнения.Хотя python все равно должен был бы импортировать TYPE_CHECKING во время выполнения, рекомендуется избегать импорта классов только для намека типа: (1) не выполняется (просто анализируется) и (2) он мог избежать циклического импорта.