#python #python-3.x
#python #python-3.x
Вопрос:
Как создать класс ввода с обратным перемещением в Python? У меня есть класс с именем input, который считывает файл вперед, возвращая по одному символу за раз, теперь я хотел бы изменить его для чтения в обратном направлении.
# Buffered input file. Returns one character at a time.
class Input:
def __init__( self, file ):
self.file = file # must open( <filename>, 'rb' )
self.length = 0
self.used = 0
self.buffer = ""
def read( self ):
if self.used < self.length: # if something in buffer
c = self.buffer[self.used]
self.used = 1
return c
else:
self.buffer = self.file.read( 2048 ) # or 2048
self.length = len( self.buffer )
if self.length == 0:
return -1
else:
c = self.buffer[0]
self.used = 1
return c
Комментарии:
1. читать в обратном направлении? вы имеете в виду от конца файла к началу?
2. К вашему сведению: python.org/dev/peps/pep-0008
3. Итак, в чем именно ваша проблема, и какой код вы пробовали? Мы вряд ли будем писать код для вас, но мы будем рады показать вам ошибки в вашем коде.
4. Я должен отредактировать части этого кода, оригинал которого читает файл от начала до конца, я должен внести в него изменения, чтобы он мог читать от конца до начала.
Ответ №1:
Я думаю, что единственный способ, которым это может работать с текстовыми файлами в Python 3, — это прочитать весь текст файла сразу, а затем вывести символы из конца загруженной вами строки. Вы не можете читать файл по частям, начиная с конца, потому что нет способа безопасно искать произвольную позицию в тексте. Если вы выбрали произвольное место (например, 2048 байт до конца файла), вы можете попасть в середину многобайтового символа. По этой причине Python не поддерживает выполнение a seek
в любом другом месте, кроме начала и конца файла, или в месте, где вы были раньше (и сохранили позицию с tell
).
Если ваш файл достаточно мал, я бы предложил что-то вроде этого:
class ReverseInput():
def __init__(self, file):
buffer = file.read() # read all text
self.rev_iter = reversed(buffer) # save a reverse iterator into the text
def read(self):
try:
return next(self.rev_iter)
except StopIteration:
return -1 # raising an exception or returning "" might be a better API
Если файл слишком велик для одновременного хранения в памяти, я полагаю, вы могли бы обойти ограничение на поиск, прочитав и отбросив блоки ограниченного размера, просматривая файл вперед и используя self.file.tell()
для сохранения местоположений, к которым вы можете вернуться позже. Вероятно, это было бы медленно, неудобно и легко испортить.
Комментарии:
1. Почему бы не использовать файл с отображением в памяти? Вы можете искать, и ОС обрабатывает подкачку, если файл слишком большой.
2. @Basic: это сработало бы для доступа к двоичным файлам, но работа с закодированным текстом все еще может быть настоящей проблемой.
3. Да, многосимвольная кодировка всегда является проблемой, но если вы используете UTF-8 или аналогичный, спецификация очень хорошо разработана и позволяет это … youtube.com/watch?v=MijmeoH9LT4