Ранее было показано, как перейти от использования объекта файла к использованию дескриптора с помощью метода объекта файла fileno, — получив дескриптор, мы можем использовать инструменты из модуля os для выполнения низкоуровневых операций с файлом. Но можно пойти и обратным путем — функция os.fdopen обертывает дескриптор файла объектом файла. Поскольку преобразования могут выполняться в обоих направлениях, мы можем выбирать любой набор инструментов — объект файла или модуль os:
>>> fdfile = os.open(r’C:\temp\spam.txt’, (os.O_RDWR | os.O_BINARY))
>>> fdfile
3
>>> objfile = os.fdopen(fdfile, ‘rb’)
>>> objfile.read()
b’Jello stdio file\r\nHello descriptor file\n’
Фактически мы можем обернуть дескриптор файла любым объектом файла, открытым в текстовом или в двоичном режиме. В текстовом режиме операции чтения и записи будут производить кодирование/деко- дирование Юникода и преобразование символов конца строки, с которыми мы познакомились выше, и для работы с ними необходимо будет использовать строки типа str, а не bytes:
C:\…\PP4E\System> python
>>> import os
>>> fdfile = os.open(r’C:\temp\spam.txt’, (os.O_RDWR | os.O_BINARY))
>>> objfile = os.fdopen(fdfile, ‘r’)
>>> objfile.read()
‘Jello stdio file\nHello descriptor file\n’
Встроенная функция open в Python 3.X также может принимать дескриптор файла вместо строки с его именем. В этом режиме она действует практически так же, как функция os.fdopen, но обеспечивает более полный контроль. Например, можно использовать дополнительные аргументы, чтобы определить кодировку для текста и подавить операцию закрытия дескриптора, которая выполняется по умолчанию. Однако на практике функция os.fdopen в версии 3.X принимает те же дополнительные аргументы, потому что она была переопределена и теперь вызывает встроенную функцию open (смотрите файл os.py в стандартной библиотеке):
C:\…\PP4E\System> python
>>> import os
>>> fdfile = os.open(r’C:\temp\spam.txt’, (os.O_RDWR | os.O_BINARY))
>>> fdfile
3
>>> objfile = open(fdfile, ‘r’, encoding=’latin1’, closefd=False)
>>> objfile.read()
‘Jello stdio file\nHello descriptor file\n’
> >> objfile = os.fdopen(fdfile, ‘r’, encoding=’latin1’, closefd=True)
> >> objfile.seek(0)
> >> objfile.read()
‘Jello stdio file\nHello descriptor file\n’
Далее в книге мы будем использовать этот прием обертывания в объекты файлов, чтобы упростить работу в текстовом режиме с каналами и другими объектами на основе дескрипторов (например, сокеты обладают методом makefile, позволяющим добиться похожего эффекта).
Использованная литература:
Марк Лутц — Программирование на Python, 4-е издание, I том, 2011