Рубрики
Без рубрики

Наследование в Питоне

Наследование питона – все, что вам нужно знать. Как видео? Посмотрите на бонусное видео вместо этого.

Автор оригинала: Chris.

У вас есть глаза твоей матери. Можно сказать, вы «унаследовали» глаза твоей матери. Как вы уже догадались, эта статья о наследовании в Python.

Наследование является одной из важнейших особенностей ориентации объекта. Это простая и интуитивно понятная концепция, но даже усовершенствованные кодеры, обходящиеся с использованием наследства, потому что у них есть это скрытое чувство не понимая его 100%. Это наносит вред своей способности писать чистый и эффективный код, а в конечном итоге – наносит вред своей способности действовать на их полный потенциал. Как вы думаете, вы могли бы сделать больше, чтобы оправдать свой потенциал? Хорошо. Затем начнем изучать наследство в Python.

Как небольшой дар признательности для чтения этого урока и улучшения ваших навыков программирования, вы получите бесплатный PDF загрузки моего объекта The Cheat Steit в конце этого учебника.

Что такое наследство в Python?

Наследование позволяет определить класс, наследующий все методы и свойства из другого класса.

  • Родительский класс , также обозначен как Базовый класс , это класс, от которого вы наследуете. В Python каждый класс может быть родительским классом.
  • Детский класс , также обозначен как Полученный класс наследовать из родительского класса. В Python вы можете создать детский класс, который наследует все методы и атрибуты от родителя, используя Класс ребенок (родитель) Синтаксис с родительским классом, заключенным в скобки.

Вот минимальный синтаксис, показывающий, как вывести у класса ребенка из родительского класса, используя подсвеченные скобки:

class Parent:
    pass

class Child(Parent):
    pass

В следующем примере вы создаете два класса Родитель и Ребенок Отказ Родитель имеет один метод P () который печатает строку «От родителя» при выполнении. Ребенок есть метод C () который печатает строку «От ребенка» и унаследованный метод P () от Родитель класс.

# Define parent and child classes
class Parent:
    def p(self):
        return 'from parent'


# Child inherits method p() from parent
class Child(Parent):
    def c(self):
        return 'from child'


# Create parent instance and run method
parent = Parent()
print(parent.p())

# Create child instance and run methods
child = Child()
print(child.p())
print(child.c())

Вывод:

from parent
from parent
from child

Вы можете увидеть, что ребенок наследует все методы и, не показано, все атрибуты из родительского класса. Это может сэкономить вам много увольнений на практике.

Обзор видео

Головоломки и отрицательный пример

Давайте посмотрим на плохой пример, не использующий наследство. Сохраняйте свои навыки понимания кода свежим, решая головоломку сначала, прежде чем читать.

class Human:

    def __init__(self, name, ff, iq):
        self.name = name
        self.ff = ff # = facebook friends
        self.iq = iq

    def befriend(self, other):
        self.ff += 1
        other.ff += 1

    def learn(self):
        self.iq += 1



class Wizard:

    def __init__(self, name, ff, iq, mana):
        self.name = name
        self.ff = ff # = facebook friends
        self.iq = iq
        self.mana = mana

    def befriend(self, other):
        self.ff += 1
        other.ff += 1

    def learn(self):
        self.iq += 1
    
    def magic_friends(self, num):
        self.ff += num if self.mana>0 else 0
        self.mana -= 100


vernon = Human("Vernon", 0, 80)
tom = Wizard("Tom", 666, 130, 100)
dumbledore = Wizard("Albus", 999, 189, 100)

dumbledore.befriend(tom)
dumbledore.befriend(vernon)
dumbledore.magic_friends(100)

print("Friends Vernon: " + str(vernon.ff))
print("Friends Tom: " + str(tom.ff))
print("Friends Dumbledore: " + str(dumbledore.ff))

Прежде чем читать дальше, у меня есть два вопроса для вас:

  1. Что такое выход вышеуказанного фрагмента кода?
  2. Какова ваша идея сделать этот код более лаконичным?

Что такое выход вышеуказанного фрагмента кода?

Давайте начнем с первого вопроса. Мы создаем два класса Человек и Волшебники Отказ Оба имеют очень похожие методы и атрибуты Отказ Единственное отличие состоит в том, что Волшебник У класса есть один дополнительный атрибут Self.mana и один дополнительный метод Magic_friends Отказ Оба метода подружиться и Magic_friends Изменить Атрибут экземпляра FF Отказ С волшебным трюком, Дамблдор получает 100 дополнительных друзей, в дополнение к Тому и Вернону.

Таким образом, результат:

"""
Friends Vernon: 1
Friends Tom: 667
Friends Dumbledore: 1101
"""

Как улучшить этот код?

Что касается второго вопроса, я уже указывал на проблему: между двумя классами есть огромные избытки Человек и Волшебник Отказ Большинство методов и атрибутов точно так же. Причина в том, что, концептуально, а Волшебник тоже Человек Отказ И каждый человек должен иметь IQ, учетную запись Facebook и имя (как вы знаете).

Другими словами: каждый Волшебник это Человек Но не каждый Человек это Волшебник Отказ

Как мы можем выразить этот факт в ориентации объекта Python?

Ответ наследие.

Мы создаем класс Человек и класс Волшебник Отказ Класс Волшебник это «детский класс» «родительского класса» Человек Отказ Таким образом, детский класс Волшебник «Наследовать» каждый атрибут и метод от родительского класса Человек Отказ Это экономит нас все избыточные определения и инициализации в Волшебник класс.

Смотрите пример:

class Human:


    def __init__(self, name, ff, iq):
        self.name = name
        self.ff = ff # = facebook friends
        self.iq = iq

    def befriend(self, other):
        self.ff += 1
        other.ff += 1

    def learn(self):
        self.iq += 1



class Wizard(Human):


    def __init__(self, name, ff, iq, mana):
        super().__init__(name, ff, iq)
        self.mana = mana

    def magic_friends(self, num):
        self.ff += num if self.mana>0 else 0
        self.mana -= 100


vernon = Human("Vernon", 0, 80)
tom = Wizard("Tom", 666, 130, 100)
dumbledore = Wizard("Albus", 999, 189, 100)

dumbledore.befriend(tom)
dumbledore.befriend(vernon)
dumbledore.magic_friends(100)

print("Friends Vernon: " + str(vernon.ff))
print("Friends Tom: " + str(tom.ff))
print("Friends Dumbledore: " + str(dumbledore.ff))

dumbledore.learn()
print("IQ Dumbledore: " + str(dumbledore.iq))

Результат точно такой же, как указано выше. Как вы можете видеть в последних двух линиях, Дамблдор все еще может вызвать метод Учиться () – Хотя это не определено в Волшебник класс. Причина в том, что Волшебник Класс наследует все методы и атрибуты из Человек класс.

Можете ли вы найти, где мы определяем наследство в коде?

Одно окончательное примечание: в конструкторе Волшебник Класс, мы называем конструктор родительского класса, используя "Super ()" Отказ Это инициализирует переменные точно так же, как родительский конструктор из Человек класс.

Вызов конструктора родительского класса с Super ()

Встроенный Python Super () Метод возвращает временный объект суперкласса, чтобы помочь вам получить доступ к его методам. Его цель состоит в том, чтобы избежать использования имени базового класса. Это также позволяет вашему классу наследовать из нескольких базовых классов.

Идея просто: использовать Super () Чтобы вызвать методы, определенные в родительских классах – будь то ваш ребенок класс наследует от одного или нескольких базовых классов. Смотрите графику:

Нужно мне вести вас через этот пример? Посмотрите видео объяснения следующим!

Далее вы узнаете обоих случаях по примеру!

Простой пример 1: Super () с одним наследством

Наследование В объектно-ориентированном программировании позволяет создавать классовую иерархию, где один класс ребенка наследует все методы от другого родительского класса. Это упрощает разработку крупных программных проектов и позволяет избежать избыточного кода. Вы можете узнать больше о концепции наследства в наших Руководство по разговору здесь Отказ

Например, следующий код определяет родительский класс Организм и детский класс Человек Отказ Детский класс использует Super () Чтобы запустить конструктор метода родительского класса.

class Organism:
    def __init__(self):
        print('I live')


class Human(Organism):
    def __init__(self):
        print('I am human')
        super().__init__()


alice = Human()

Вывод:

I am human
I live

Здесь вы называете базовый класс организм, используя следующий код:

super().__init__()

Семантически эквивалентный звонок кода будет:

Organism.__init__(self)

Вы называете __init __ () Метод на базовом классе Организм и передайте ссылку на экземпляр вызова в качестве аргумента. Таким образом, вы также можете изменить внутренние атрибуты Я экземпляр в конструкторе базового класса.

Однако преимущество использования Super () .__ init __ () по сравнению с Parentclass .__ init __ (Self) Это то, что вы не позвоните в родительский класс явно. Это выгодно, потому что он каникует ребенка из родительского класса. Например, если вы изменили имя Parentclass к NewParentClass метод с использованием Super () будет превосходить, потому что он все равно будет работать, а метод, использующий Parentclass .__ init __ (Self) будет бросать ошибку.

Пример 2: Супер () с несколькими наследованием

Один из уникальных функций Python по сравнению с другими языками программирования состоит в том, что это позволяет Многократное наследование Отказ

Многократное наследование означает, что класс может наследовать от нескольких родителей. Например, класс Человек Может наследовать от двух родительских классов: Организм и Мыслитель Отказ Скажем, вы определяете метод Live () в организме и думаю () в мыслителе. Если человеческий объект наследует от обоих классов, он может позвонить Live () и думаю () в то же время! Вы используете Super () Способ для вызова этих функций:

class Organism:
    def live(self):
        print('I live')


class Thinker:
    def think(self):
        print('I think')


class Human(Organism, Thinker):
    def __init__(self):
        print('I am human')
        super().live()
        super().think()
 

alice = Human()

Вывод:

I am human
I live
I think

Я должен упомянуть, что в этом примере вы также могли бы назвать Self.live () и self.Том () В классе Человек вместо Super (). Живи () и Super (). думаю () Отказ Выходность будет одинаковым в обоих случаях. На практике вы бы использовали бывшие для Методы экземпляра и последний за Методы класса Отказ Разница между оба объясняется в нашем руководстве в блоге здесь.

Python OOP Cheat лист

Поздравляем, вы прочитаете всю статью. Вот небольшое вознаграждение за ваши усилия: моим объектно-ориентационной терминологией Cheat лист!

Скачать этот чит-лист в виде PDF

Вы также можете ознакомиться с моим углубленным учебным пособием на русском Python с большим количеством бесплатных чисных листов PDF о различных темах в Python, таких как ключевые слова, структуры данных, списки, наборы, Numpy, Pandas и многие другие. Просто наденьте свое письмо здесь и скачайте мои бесплатные чит-листы:

Куда пойти отсюда?

Стратегия бьет тактику в долгосрочной перспективе. Вам нужно иметь стратегию обучения на месте для мастера Python. Ты?

Если нет, получите быструю победу, загрузив наш популярный Python Cheat Sheet (High-Res PDF), а также долгосрочное решение вашей проблемы (почти ежедневные уроки Python). Это на 100% бесплатно. Без спама. Гарантировано.

Работая в качестве исследователя в распределенных системах, доктор Кристиан Майер нашел свою любовь к учению студентов компьютерных наук.

Чтобы помочь студентам достичь более высоких уровней успеха Python, он основал сайт программирования образования Finxter.com Отказ Он автор популярной книги программирования Python One-listers (Nostarch 2020), Coauthor of Кофе-брейк Python Серия самооставленных книг, энтузиаста компьютерных наук, Фрилансера и владелец одного из лучших 10 крупнейших Питон блоги по всему миру.

Его страсти пишут, чтение и кодирование. Но его величайшая страсть состоит в том, чтобы служить стремлению кодер через Finxter и помогать им повысить свои навыки. Вы можете присоединиться к его бесплатной академии электронной почты здесь.