Другое дело, как будет работать такой кадавр - будут ли наследникам доступны методы потомка - ради чего наследование и делалось? Конечно можно сделать и более топорно, создав базовый клас фасадом для спрятанного в нем драйвера-реализации, но есть и вторая проблема. Не получается сделать низкоуровневый драйвер ничего не знающим о тех классах, что будут его использовать - в разных высокоуровневых классах разный достаточно высокоуровневый код, достаточно зависящий и от драйвера и от предметной области, и я пока не придумал, как избежать декартова произведения.
Тут или делать методы в стиле "подготовить обучающие/тестовые данные в формате класса A/B/C под драйвер 1/2/3" или делать много низкоуровневых драйвероспецифичных методов. Второе вроде как правильнее, но тогда типы передаваемых параметров и возвращаемых результатов будут тоже зависеть от драйвера. Для языка с динамической типизацией это невелика беда, но как общее решение - так себе. Неаккуратненько как-то!
Пока еще думаю.
---- наутро --
Да! Верно говорят, что с проблемой нужно переспать - скорее всего самым интересным способом будет готовит данные в общем (numpy) формате, преобразуя перед самым использованием, а иногда и преобразовывать не нужно будет.