…·········self.name = name
…
>>> class MDPerson(Person):
…·····def __init__(self, name):
…·········self.name = "Doctor " + name
…
>>> class JDPerson(Person):
…·····def __init__(self, name):
…·········self.name = name +", Esquire"
…
В этих случаях метод инициализации __init__() принимает те же аргументы, что и родительский класс Person, но внутри объекта сохраняет значение переменной name разными способами:
>>> person = Person('Fudd')
>>> doctor = MDPerson('Fudd')
>>> lawyer = JDPerson('Fudd')
>>> print(person.name)
Fudd
>>> print(doctor.name)
Doctor Fudd
>>> print(lawyer.name)
Fudd, Esquire
Добавление метода
В класс-потомок можно также добавить метод, которого не было в родительском классе. Возвращаясь к классам Car и Yugo, мы определим новый метод need_a_push() только для класса Yugo:
>>> class Car():
…·····def exclaim(self):
…·········print("I'm a Car!")
…
>>> class Yugo(Car):
…·····def exclaim(self):
…·········print("I'm a Yugo! Much like a Car, but more Yugo-ish.")
…·····def need_a_push(self):
…·········print("A little help here?")
…
Далее создадим объекты классов Car и Yugo:
>>> give_me_a_car = Car()
>>> give_me_a_yugo = Yugo()
Объект класса Yugo может реагировать на вызов метода need_a_push():
>>> give_me_a_yugo.need_a_push()
A little help here?
А объект общего класса Car — нет:
>>> give_me_a_car.need_a_push()
Traceback (most recent call last):
··File "
AttributeError: 'Car' object has no attribute 'need_a_push'
К этому моменту класс Yugo может делать что-то, чего не может делать класс Car, и теперь мы точно можем определить отдельную личность класса Yugo.
Просим помощи у предка с помощью ключевого слова super
Мы видели, как класс-потомок может добавить или перегрузить метод класса-предка. Но что, если вам нужно вызвать оригинальный метод родительского класса? «Рад, что вы спросили», — говорит метод super(). Мы определим новый класс, который называется EmailPerson и представляет объект класса Person, содержащий адрес электронной почты. Для начала запишем наше привычное определение класса Person:
>>> class Person():
…·····def __init__(self, name):
…·········self.name = name
…
Обратите внимание на то, что вызов метода __init__() в следующем подклассе имеет дополнительный параметр email:
>>> class EmailPerson(Person):
…·····def __init__(self, name, email):
…·········super().__init__(name)
…·········self.email = email
Когда вы определяете метод __init__() для своего класса, вы заменяете метод __init__() родительского класса, который больше не вызывается автоматически. В результате вам нужно вызывать его явно. Происходит следующее.
• Метод super() получает определение родительского класса Person.
• Метод __init__() вызывает метод Person.__init__(). Последний заботится о том, чтобы передать аргумент self суперклассу, поэтому вам нужно лишь передать опциональные аргументы. В нашем случае единственным аргументом класса Person() будет name.
• Строка self.email = email — это новый код, который отличает класс EmailPerson от класса Person.
Теперь создадим одну персону:
>>> bob = EmailPerson('Bob Frapples', '[email protected]')
Мы должны иметь доступ к атрибутам name и email:
>>> bob.name
'Bob Frapples'
>>> bob.email
Почему бы нам просто не определить новый класс так, как показано далее?
>>> class EmailPerson(Person):
…·····def __init__(self, name, email):
…·········self.name = name
…·········self.email = email