#python #python-3.x #python-2.x #porting
#python #python-3.x #python-2.x #перенос
Вопрос:
Я переношу некоторый устаревший код Python 2, и у меня есть этот класс:
class myfile(file):
"Wrapper for file object whose read member returns a string buffer"
def __init__ (self, *args):
return file.__init__ (self, *args)
def read(self, size=-1):
return create_string_buffer(file.read(self, size))
Он используется как файловый объект:
self._file = myfile(name, mode, buffering)
self._file.seek(self.si*self.blocksize)
Я пытаюсь реализовать это в Python 3 следующим образом:
class myfile(io.FileIO):
"Wrapper for file object whose read member returns a string buffer"
def __init__(self, name, mode, *args, **kwargs):
super(myfile, self).__init__(name, mode, closefd=True, *args, **kwargs)
def read(self, size=-1):
return create_string_buffer(self.read(size))
Проблема в том, что конструктор для FileIO не принимает buffering
аргумент, и Python выдает TypeError: fileio() takes at most 3 arguments (4 given)
ошибку.
Функция открытия Python 3 — это то, что мне нужно. Могу ли я наследовать от этого? Я посмотрел на класс PyFile_FromFd, но ему нужен дескриптор открытого файла, и я обеспокоен тем, что поведение не будет таким же.
Спасибо!!!
Комментарии:
1. Вы уверены, что этот класс вообще еще нужен? Что
create_string_buffer
делает?
Ответ №1:
Вы не можете наследовать от open
. Аргумент буферизации изменяет возвращаемый класс, поэтому open
реализован как функция, которая может возвращать один из нескольких классов. Лучший вариант — сделать то же самое с вашими собственными классами-оболочками, если это необходимо.
Основная идея реализации заключается в:
myfile
является ли функция с сигнатурой, подобнойopen
- У вас есть два класса, один из которых наследуется от
FileIO
, другой отBufferedReader
. - При
myfile
вызове он проверяетbuffering
аргумент и либо создает и возвращаетFileIO
производный подкласс (если он небуферизован), либо создает обычный небуферизованныйFileIO
класс сopen
, затем переносит его в вашBufferedReader
производный подкласс.
Ответ №2:
Одним из быстрых решений было бы исправление обезьяны:
def myfile(*args, **kwargs):
f = open(*args, **kwargs)
def read(size=-1):
return create_string_buffer(f._read(size))
f._read = f.read # save old read method
f.read = read # patch
return f