Учитывая, что Python допускает множественное наследование, как выглядит идиоматическое наследование в Python?
В языках с единичным наследованием, таких как Java, наследование будет использоваться, когда вы можете сказать, что один объект «a-a» другого объекта и вы хотите разделить код между объектами (от родительского объекта до дочернего объекта). Например, вы можете сказать, что Dogэто Animal:
public class Animal {...}
public class Dog extends Animal {...}
Но поскольку Python поддерживает множественное наследование, мы можем создать объект, составив множество других объектов вместе. Рассмотрим пример ниже:
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
Это приемлемое или хорошее использование множественного наследования в Python? Вместо того чтобы говорить, что наследование - это когда один объект «является-а» другого объекта, мы создаем Userмодель, состоящую из UserServiceи LoggingService.
Вся логика для баз данных или сетевых операций может храниться отдельно от Userмодели, помещая их в UserServiceобъект и сохраняя всю логику для входа в систему LoggingService.
Я вижу некоторые проблемы с этим подходом:
- Создает ли это объект Бога? Поскольку
Userнаследует или состоит из,UserServiceиLoggingServiceдействительно ли он следует принципу единой ответственности? - Для того, чтобы получить доступ к методам родительского / следующего в строке объекта (например,
UserService.validate_credentialsмы должны использоватьsuper. Это немного затрудняет просмотр объекта, который будет обрабатывать этот метод, и не так ясно, как, скажем, , создаваяUserServiceи делая что-то вродеself.user_service.validate_credentials
Что бы Pythonic способ реализовать вышеупомянутый код?