Нет необходимости передавать self.__class__.__name__
в super().__init__
- метод __init__
суперкласса может обращаться к нему напрямую, точно так же, как ваш метод __repr__
. Таким образом, атрибут self.type
является избыточным.
Вот разумный способ написать __repr__
в базовом классе: вместо использования собственного атрибута _kwargs
вы можете использовать собственный __dict__
объекта. Сюда входит атрибут identifier
, поэтому вам не нужно добавлять его отдельно.
from collections import Counter
class Component:
cnt = Counter()
def __init__(self, **kwargs):
_type = self.__class__.__name__
Component.cnt[_type] += 1
self.identifier = _type[0] + str(Component.cnt[_type])
super().__init__(**kwargs) # co-operative subclassing
def __repr__(self):
return '{0}({1})'.format(
self.__class__.__name__,
', '.join(
'{0}={1!r}'.format(k, v)
for k, v in self.__dict__.items()))
class Battery(Component):
# outbound is positive terminal
def __init__(self, *, voltage, **kwargs):
self.voltage = voltage
super().__init__(**kwargs) # co-operative subclassing
Пример:
>>> b = Battery(voltage=9) # keyword-only argument for co-operative subclassing
>>> b
Battery(voltage=9, identifier='B1')
Я пометил часть кода с комментариями о кооперативное наследование . В иерархии классов каждый метод __init__
может принимать свои аргументы в качестве ключевых слов и передавать его **kwargs
методу super().__init__
, чтобы вам не приходилось писать одни и те же имена аргументов несколько раз в обоих классах.
Также важно позвонить super().__init__
даже из вашего базового класса , если вы используете множественное наследование. Даже если вы не используете множественное наследование, это вызовет object.__init__
, что позволит убедиться в отсутствии «неиспользуемых» аргументов, которые не были обработаны другим методом __init__
.