Étant donné que Python permet l'héritage multiple, à quoi ressemble l'héritage idiomatique en Python?
Dans les langages à héritage unique, comme Java, l'héritage serait utilisé lorsque vous pourriez dire qu'un objet "est-a" d'un autre objet et que vous souhaitez partager du code entre les objets (de l'objet parent à l'objet enfant). Par exemple, vous pourriez dire que Dog
c'est Animal
:
public class Animal {...}
public class Dog extends Animal {...}
Mais comme Python prend en charge l'héritage multiple, nous pouvons créer un objet en composant de nombreux autres objets ensemble. Considérez l'exemple ci-dessous:
class UserService(object):
def validate_credentials(self, username, password):
# validate the user credentials are correct
pass
class LoggingService(object):
def log_error(self, error):
# log an error
pass
class User(UserService, LoggingService):
def __init__(self, username, password):
self.username = username
self.password = password
def authenticate(self):
if not super().validate_credentials(self.username, self.password):
super().log_error('Invalid credentials supplied')
return False
return True
Est-ce une utilisation acceptable ou bonne de l'héritage multiple en Python? Au lieu de dire que l'héritage est lorsqu'un objet "est-a" d'un autre objet, nous créons un User
modèle composé de UserService
et LoggingService
.
Toute la logique des opérations de base de données ou de réseau peut être séparée du User
modèle en les plaçant dans l' UserService
objet et en conservant toute la logique de connexion dans le LoggingService
.
Je vois certains problèmes avec cette approche:
- Est-ce que cela crée un objet divin? Puisqu'il
User
hérite de, ou est composé de,UserService
etLoggingService
suit-il vraiment le principe de la responsabilité unique? - Afin d'accéder aux méthodes sur un objet parent / suivant (par exemple,
UserService.validate_credentials
nous devons utilisersuper
. Cela rend un peu plus difficile de voir quel objet va gérer cette méthode et n'est pas aussi clair que, par exemple , instancierUserService
et faire quelque chose commeself.user_service.validate_credentials
Quelle serait la façon Pythonique d'implémenter le code ci-dessus?