In Python 2, file data was not decoded while reading. Finding reverse and multibyte encodings doesn't mix well (you can't know where the next character will run), so it's disabled for Python 3.
You can still search for the underlying buffer object using the TextIOBase.buffer attribute, but then you will have to reconnect the new TextIOBase , since the current shell no longer knows where it is:
import io file.buffer.seek(-3, 2) file = io.TextIOWrapper( file.buffer, encoding=file.encoding, errors=file.errors, newline=file.newlines)
I copied any information about encoding and processing strings into an io.TextIOWrapper() object.
Note that this can decrypt decoding for UTF-16, UTF-32, UTF-8 and other multibyte codecs.
Demo:
>>> import io >>> with open('demo.txt', 'w') as out: ... out.write('Demonstration\nfor seeking from the end') ... 38 >>> with open('demo.txt') as inf: ... print(inf.readline()) ... inf.buffer.seek(-3, 2) ... inf = io.TextIOWrapper(inf.buffer) ... print(inf.readline()) ... Demonstration 35 end
You can wrap this in a utility function:
import io def textio_seek(fobj, amount, whence=0): fobj.buffer.seek(amount, whence) return io.TextIOWrapper( fobj.buffer, encoding=fobj.encoding, errors=fobj.errors, newline=fobj.newlines)
and use it like:
with open(somefile) as file:
Using the file object as a context manager still works because the original reference to the object object is still bound to the original file buffer object and, therefore, can be used to close the file.