Guilherme, a resposta é: Depende! Mas primeiro, precisamos lembrar que os exemplos utilizados nos cursos são didáticos. Apesar de serem feitos por pessoas mais do que competentes para isso o foco dos códigos é ensinar alguns conceitos e nem sempre acabam ficando otimizados. Não é para ser mesmo na minha opinião.
No front de batalha a gente acaba aprendendo, às vezes da pior forma, algumas práticas para driblar deficiências das linguagens (na verdade das ferramentas que implementam as linguagens) . Lembro desse problema com JAVA, algo que fazia também era isolar as classes quando percebia que uma estava com problemas de performance.
Com relação à herança do Python, sendo sincero, nunca usei em um trabalho que demandasse tanta performance a ponto de dar problemas. Pode ser que pessoas mais experientes e que participaram de projetos grandes tenham passado por isso.
Conclusão, eu continuaria a usar heranças porque acho que faz parte da OO e é uma boa prática. MAS se percebesse que a performance ficaria comprometida e isso fosse um problema eu tomaria outros caminhos como os IDs que você citou.