Как вызвать переменную из другого класса python
Перейти к содержимому

Как вызвать переменную из другого класса python

  • автор:

Наследование в Python 3

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

Данное руководство ознакомит вас с основными аспектами наследования в Python: с работой родительских и дочерних классов, переопределением методов и атрибутов, функцией super() и множественным наследованием.

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

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

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

Предположим, что у нас есть класс Parent с переменными last_name, height, и eye_color. Подкласс Child может наследовать эти переменные из класса Parent, то есть повторно использовать этот код. Это позволяет уменьшить объём кода и снизить избыточность.

Родительские классы

Родительский, или базовый класс создаёт шаблон кода, который в дальнейшем может наследоваться дочерними классами. Родительским классом может быть любой класс. Базовые классы – это не просто шаблоны, а полноценные функционирующие классы.

Предположим, у нас есть общий родительский класс Bank_account с дочерними классами Personal_account и Business_account. Многие параметры классов Personal_account и Business_account будут совпадать. Такие параметры можно наследовать из родительского класса Bank_account. В подклассе Business_account будут индивидуальные параметры (например, методы сбора деловых документов и форм и переменная employee_identification_number).

Аналогичным образом, класс Animal может содержать методы eating() и sleeping(), а подкласс Snake помимо вышеперечисленных наследуемых методов может также содержать методы hissing() и slithering().

Для примера попробуйте создать родительский класс Fish (в дальнейшем мы используем его, чтобы создать различные подклассы с типами рыб).

Создайте файл fish.py и добавьте в него метод конструктора __init__(), который будет содержать переменные first_name и last_name для каждого подкласса (или объекта) Fish.

class Fish:
def __init__(self, first_name, last_name=»Fish»):
self.first_name = first_name
self.last_name = last_name

Переменная last_name содержит строку “Fish”, потому что почти все подклассы будут использовать это значение.

Добавьте в файл другие методы:

class Fish:
def __init__(self, first_name, last_name=»Fish»):
self.first_name = first_name
self.last_name = last_name
def swim(self):
print(«The fish is swimming.»)
def swim_backwards(self):
print(«The fish can swim backwards.»)

Теперь в файле есть методы swim() и swim_backwards(), которые будут наследоваться подклассами.

Добавьте другие атрибуты в метод __init__():

class Fish:
def __init__(self, first_name, last_name=»Fish»,
skeleton=»bone», eyelids=False):
self.first_name = first_name
self.last_name = last_name
self.skeleton = skeleton
self.eyelids = eyelids
def swim(self):
print(«The fish is swimming.»)
def swim_backwards(self):
print(«The fish can swim backwards.»)

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

Дочерние классы

Дочерние классы, или подклассы – это классы, которые наследуют параметры родительских классов. Каждый дочерний класс сможет использовать методы и переменные родительского класса.

К примеру, дочерний класс Goldfish может наследовать из класса Fish функцию swim().

Дочерние классы начинаются немного иначе. В первой строке нужно передать родительский класс:

Класс Trout является дочерним по отношению к классу Fish (родительский класс нужно указать в круглых скобках).

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

.
class Trout(Fish):
pass

Теперь создайте объект Trout и наследуйте методы родительского класса, не добавляя новых:

.
class Trout(Fish):
pass
terry = Trout(«Terry»)
print(terry.first_name + » » + terry.last_name)
print(terry.skeleton)
print(terry.eyelids)
terry.swim()
terry.swim_backwards()

Теперь в файле есть объект Trout, который использует все методы класса Fish несмотря на то, что они не объявлены в самом объекте. Нужно только передать значение “Terry” переменной first_name; все остальные переменные уже инициализированы.

Запустите программу. Вы получите:

Terry Fish
bone
False
The fish is swimming.
The fish can swim backwards.

Создайте другой дочерний класс, теперь уже добавив новые методы. Класс будет называться Clownfish, его индивидуальный метод – live_with_anemone.

.
class Clownfish(Fish):
def live_with_anemone(self):
print(«The clownfish is coexisting with sea anemone.»)

Создайте объект Clownfish:

.
casey = Clownfish(«Casey»)
print(casey.first_name + » » + casey.last_name)
casey.swim()
casey.live_with_anemone()

Запустив программу, вы получите такой вывод:

Casey Fish
The fish is swimming.
The clownfish is coexisting with sea anemone.

Как видите, объект casey использует методы __init__() и swim() родительского класса Fish и индивидуальный метод live_with_anemone().

Если попробовать использовать метод live_with_anemone() в объекте Trout, получится ошибка:

terry.live_with_anemone()
AttributeError: ‘Trout’ object has no attribute ‘live_with_anemone’

Это потому, что метод live_with_anemone() принадлежит исключительно дочернему классу Clownfish.

Переопределение методов родительского класса

Только что вы создали дочерний класс Trout, который с помощью ключевого слова pass полностью наследует методы родительского класса Fish, и дочерний класс Clownfish, который не только наследует методы родительского класса, но и использует свой собственный метод.

Однако в некоторых случаях нужно использовать не все, а только отдельные методы родительского класса. Для этого методы родительского класса можно переопределять.

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

Для примера создайте дочерний класс Shark. При создании класса Fish использовался параметр skeleton=”bone”, но в случае с классом Sharkэто неверно. Переопределите этот параметр.

Примечание: Что касается проектирования программы, если бы переопределяемый параметр использовался несколькими классами, а не одним, лучше было бы создать для них отдельный родительский класс.

Переопределите метод конструктора __init__() и метод swim_backwards(). Метод swim() изменять не нужно. Дочерний класс будет выглядеть так:

.
class Shark(Fish):
def __init__(self, first_name, last_name=»Shark»,
skeleton=»cartilage», eyelids=True):
self.first_name = first_name
self.last_name = last_name
self.skeleton = skeleton
self.eyelids = eyelids
def swim_backwards(self):
print(«The shark cannot swim backwards, but can sink backwards.»)

Параметры метода конструктора __init__() были переопределены; теперь переменная last_name имеет значение “Shark”, переменная skeleton имеет значение “cartilage”, а eyelids – значение True.

Метод swim_backwards() теперь выводит другое значение, а не то, которое определено в родительском классе Fish.

Теперь создайте экземпляр класса Shark, который будет использовать метод swim() родительского класса Fish.

.
wally = Shark(«Wally»)
print(wally.first_name + » » + wally.last_name)
wally.swim()
wally.swim_backwards()
print(wally.eyelids)
print(wally.skeleton)

Запустите этот код, и вы получите:

Wally Shark
The fish is swimming.
The shark cannot swim backwards, but can sink backwards.
True
cartilage

В дочернем классе Shark методы __init__() и swim_backwards() успешно переопределены.

Функция super()

С помощью функции super() вы можете получить доступ к унаследованным методам, которые были перезаписаны в объекте класса.

Функция super() вызывает родительский метод в дочерний и использует его. Например, это позволяет переопределить один из аспектов родительского метода, а затем вызвать остальную часть исходного родительского метода.

К примеру, в программе, которая выставляет оценки студентам, внутри родительского класса Grade может быть дочерний класс Weighted_grade. В классе Weighted_grade можно переопределить метод родительского класса calculate_grade() и унаследовать остальные методы без изменений. Для этого и нужна функция super().

Обычно функция super() используется в методе конструктора __init__(), потому что именно там, скорее всего, появятся уникальные методы дочернего класса.

Попробуйте изменить дочерний класс Trout. Добавьте переменную water в метод __init__() и присвойте ей значение “freshwater”. Остальные методы родительского класса можно наследовать без изменений.

.
class Trout(Fish):
def __init__(self, water = «freshwater»):
self.water = water
super().__init__(self)
.

Метод __init__() класса Trout был переопределён. Он иначе реализует методы __init__() родительского класса Fish. В методе __init__() класса Trout был явно инициализирован метод __init__() класса Fish.

Поскольку метод переопределён, больше не нужно передавать first_name как параметр Trout. Если бы вы передали параметр, параметр freshwater был бы сброшен. Поэтому переменную first_name нужно инициализировать путём вызова в объекте.

Теперь можно вызвать инициализированные переменные родительского класса, а также использовать уникальную дочернюю переменную.

.
terry = Trout()
# Инициализация first name
terry.first_name = «Terry»
# Использование родительского метода __init__() с помощью функции super()
print(terry.first_name + » » + terry.last_name)
print(terry.eyelids)
# Дочерний метод __init__()
print(terry.water)
# Родительский метод swim()
terry.swim()
Terry Fish
False
freshwater
The fish is swimming.

Как видите, объект terry класса Trout может использовать свой метод __init__() с переменной water и родительский метод __init__() класса Fish с переменными first_name, last_name и eyelids.

Множественное наследование

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

Попробуйте создать класс Coral_reef, дочерний по отношению к классам Coral и Sea_anemone. Создайте в каждом классе метод и передайте его с помощью ключевого слова pass в дочерний класс Coral_reef.

class Coral:
def community(self):
print(«Coral lives in a community.»)
class Anemone:
def protect_clownfish(self):
print(«The anemone is protecting the clownfish.»)
class CoralReef(Coral, Anemone):
pass

Класс Coral содержит метод community(), который выводит одну строку текста, а класс Anemone содержит метод protect_clownfish(), который отображает другую строку. После этого оба класса вызываются в кортеж. Таким образом класс Coral может наследовать оба родительских класса.

Читайте также: Кортежи в Python 3

Создайте объект класса Coral:

.
great_barrier = CoralReef()
great_barrier.community()
great_barrier.protect_clownfish()

Объект great_barrier класса CoralReef использует методы обоих родительских классов.

Coral lives in a community.
The anemone is protecting the clownfish.

Как видите, множественное наследование работает правильно.

Множественное наследование позволяет использовать методы нескольких родительских классов внутри одного дочернего класса. Если в родительских классах присутствует один и тот же метод, дочерний класс унаследует его из того родительского класса, который идёт первым в кортеже.

Заключение

Теперь вы знакомы с основами наследования в Python 3 и умеете создавать родительские и дочерние классы, переопределять методы, использовать функцию super() и использовать множественное наследование.

Наследование в объектно-ориентированном программировании позволяет соблюдать принцип разработки DRY («don’t repeat yourself»), благодаря чему программа содержит меньше повторяющихся блоков кода. Наследование также заставляет разработчиков заранее продумывать конструкцию программы.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *