Безопасно ли открывать файл несколько раз сразу в Python?
Я, кажется, помню случаи на языках более низкого уровня, что открытие файла более одного раза в программе может привести к общему указателю поиска. Возясь в Python немного, это, похоже, не происходит для меня:
$ cat file.txt
first line!
second
third
fourth
and fifth
>>> f1 = open('file.txt')
>>> f2 = open('file.txt')
>>> f1.readline()
'first line!n'
>>> f2.read()
'first line!nsecondnthirdnfourthnand fifthn'
>>> f1.readline()
'secondn'
>>> f2.read()
''
>>> f2.seek(0)
>>> f1.readline()
'thirdn'
известно ли, что такое поведение безопасно? Мне трудно найти источник, говорящий, что все в порядке, и было бы очень полезно, если бы я мог положиться на это.
Я не вижу позицию как атрибут объекта file, иначе у меня было бы больше уверенности в этом. Я знаю, что он может храниться внутри итератора, но idk как .tell () добрался бы до него в этом случае.
>>> dir(f1)
['__class__', '__delattr__', '__doc__', '__getattribute__', '__hash__',
'__init__', '__iter__', '__new__', '__reduce__', '__reduce_ex__', '__repr__',
'__setattr__', '__str__', 'close', 'closed', 'encoding', 'fileno', 'flush',
'isatty', 'mode', 'name', 'newlines', 'next', 'read', 'readinto', 'readline',
'readlines', 'seek', 'softspace', 'tell', 'truncate', 'write', 'writelines',
'xreadlines']
обновление
На странице 161 из Ссылка На Python Essential в нем говорится
один и тот же файл может быть открыт более одного раза в одной программе (или в разные программы.) Каждый экземпляр открытого файла имеет свой собственный указатель файла, которым можно управлять независимо.
Так что, похоже, на самом деле безопасно, определенное поведение
1 ответов
в современной ОС (после 1969 для UNIX-подобных ОС или после 2000 для Windows, и, вероятно, до этого, но я считаю Win2K первым "современным" Windows), каждый экземпляр открытого файла (файловый дескриптор) имеет свой собственный указатель поиска. В Python нет магии file
класс, который заставит экземпляры делиться состоянием;file
- Это оболочка для обычного дескриптора файла C, который сам инкапсулирует дескриптор файла ОС и реализацию file.tell()
и file.seek()
вызовите соответствующий C stdio
функции. (Для грязной подробности ознакомиться с CPython это fileobject.c
.) Могут быть различия между поведением библиотеки C и поведением базовой ОС, но в данном конкретном случае это не фактор.
если вы используете IronPython или Jython, он будет использовать стандартный объект файла .Net или Java для его базовой реализации, которая, в свою очередь, будет использовать стандартную библиотеку C или реализацию ОС.
так что ваш подход-это хорошо, если вы как работает Python на некоторые нестандартные ОС с причудливыми ввода/вывода.
вы можете получить неожиданные результаты при записи, если вы не промыть своевременно; данные могут зависать в памяти в течение некоторого времени, прежде чем он фактически попадает на диск и доступен для других дескрипторов файлов, которые вы открыли в том же файле. Как отмечает абарнерт в комментарии, это в любом случае проблематично, за исключением очень простых случаев.