Python наследование объектов

Наследование. Урок 4 курса

Python наследование объектов

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

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

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

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

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

class Table: def __init__(self, l, w, h): self.lenght = l self.width = w self.height = h class KitchenTable(Table): def setPlaces(self, p): self.places = p class DeskTable(Table): def square(self): return self.width * self.length

В данном случае классы KitchenTable и DeskTable не имеют своих собственных конструкторов, поэтому наследуют его от родительского класса. При создании экземпляров этих столов, передавать аргументы для __init__() обязательно, иначе возникнет ошибка:

>>> from test import *>>> t1 = KitchenTable()Traceback (most recent call last): File “”, line 1, in TypeError: __init__() missing 3 required positional arguments: 'l', 'w', and 'h'>>> t1 = KitchenTable(2, 2, 0.7)>>> t2 = DeskTable(1.5, 0.8, 0.75)>>> t3 = KitchenTable(1, 1.2, 0.8)

Несомненно можно создавать столы и от родительского класса Table. Однако он не будет, согласно неким родственным связям, иметь доступ к методам setPlaces() и square(). Точно также как объект класса KitchenTable не имеет доступа к единоличным атрибутам сестринского класса DeskTable.

>>> t4 = Table(1, 1, 0.5)>>> t2.square()1.2000000000000002>>> t4.square()Traceback (most recent call last): File “”, line 1, in AttributeError: 'Table' object has no attribute 'square'>>> t3.square()Traceback (most recent call last): File “”, line 1, in AttributeError: 'KitchenTable' object has no attribute 'square'

В этом смысле терминология “родительский и дочерний класс” не совсем верна. Наследование в ООП – это скорее аналог систематизации и классификации наподобие той, что есть в живой природе. Все млекопитающие имеют четырехкамерное сердце, но только носороги – рог.

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

Что если в подклассе нам не подходит код метода его надкласса. Допустим, мы вводим еще один класс столов, который является дочерним по отношению к DeskTable. Пусть это будут компьютерные столы, при вычислении рабочей поверхности которых надо отнимать заданную величину. Имеет смысл внести в этот новый подкласс его собственный метод square():

class ComputerTable(DeskTable): def square(self, e): return self.width * self.length – e

При создании объекта типа ComputerTable по-прежнему требуется указывать параметры, так как интерпретатор в поисках конструктора пойдет по дереву наследования сначала в родителя, а потом в прародителя и найдет там метод __init__().

Однако когда будет вызываться метод square(), то поскольку он будет обнаружен в самом ComputerTable, то метод square() из DeskTable останется невидимым, т. е. для объектов класса ComputerTable он окажется переопределенным.

>>> from test import ComputerTable>>> ct = ComputerTable(2, 1, 1)>>> ct.square(0.3)1.7

Дополнение, оно же расширение, метода

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

class ComputerTable(DeskTable): def square(self, e): return DeskTable.square(self) – e

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

Рассмотрим другой пример. Допустим, в классе KitchenTable нам не нужен метод, поле places должно устанавливаться при создании объекта в конструкторе. В классе можно создать собсвенный конструктор с чистого листа, чем переопределить родительский:

class KitchenTable(Table): def __init__(self, l, w, h, p): self.length = l self.width = w self.height = h self.places = p

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

class KitchenTable(Table): def __init__(self, l, w, h, p): Table.__init__(self, l, w, h) self.places = p

Теперь при создании объекта типа KitchenTable надо указывать в конструкторе четыре аргумента. Три из них будут переданы выше по лестнице наследования, а четвертый оприходован на месте.

>>> tk = KitchenTable(2, 1.5, 0.7, 10)>>> tk.places10>>> tk.width 1.5

Практическая работа

Разработайте программу по следующему описанию.

В некой игре-стратегии есть солдаты и герои. У всех есть свойство, содержащее уникальный номер объекта, и свойство, в котором хранится принадлежность команде. У солдат есть метод “иду за героем”, который в качестве аргумента принимает объект типа “герой”. У героев есть метод увеличения собственного уровня.

В основной ветке программы создается по одному герою для каждой команды. В цикле генерируются объекты-солдаты. Их принадлежность команде определяется случайно. Солдаты разных команд добавляются в разные списки.

Измеряется длина списков солдат противоборствующих команд и выводится на экран. У героя, принадлежащего команде с более длинным списком, поднимается уровень.

Отправьте одного из солдат первого героя следовать за ним. Выведите на экран идентификационные номера этих двух юнитов.

Курс с примерами решений практических работ: android-приложение, pdf-версия.

Источник: https://younglinux.info/oopython/inheritance.php

Python: ООП — наследование классов

Python наследование объектов

Понимание наследования в ООП и классах Python обязательно для понимания.

Рассмотрим простые примеры наследования.

Возьмём код из статьи Python: классы — краткий обзор: аргументы, методы и специальные методы, импорт классов:

class thisIsClass: '''This is class documentation''' # зададим два аргумента arg1 = 'string' arg2 = 100 # зададим два аргумента – changearg1, changearg2 # и после символа = задаём значения по-умолчанию def __init__(self, changearg1='Default value 1', changearg2='Default value 2'): # переопределяем уже созданные аргументы arg1 и arg2 self.arg1 = changearg1 self.arg2 = changearg2 # создадём пустой экземпляр (или “объект”) класса class_instance_def = thisIsClass() print 'nPrinting default arguments from __init__:' print (class_instance_def.arg1, class_instance_def.arg2) # создадём экземпляр (или “объект”) класса с аргументами class_instance_changed = thisIsClass('This is first argument', 'This is second argument') print 'nPrinting changed arguments from __init__:' print (class_instance_changed.arg1, class_instance_changed.arg2

В нём мы уже сталкиваемся с понятием «наследование«,так как при создании объекта class_instance_def = thisIsClass() — он наследует все атрибуты класса, к которым мы потом обращаемся:

print (class_instance_def.arg1, class_instance_def.arg2)

Однако, для полноценного понимания и использования наследования в классах — необходимо создать новый класс, который сможет использовать атрибуты своего родительского (или «супер«) класса.

Для этого — создадим новый класс, после имени которого в скобках укажем имя родительского класса:

class thisIsClass: '''This is class documentation''' # зададим два аргумента arg1 = 'string' arg2 = 100 # зададим два аргумента – changearg1, changearg2 # и после символа = задаём значения по-умолчанию def __init__(self, changearg1='Default value 1', changearg2='Default value 2'): # переопределяем уже созданные аргументы arg1 и arg2 self.arg1 = changearg1 self.arg2 = changearg2 # создадём пустой экземпляр (или “объект”) класса class_instance_def = thisIsClass() print 'nPrinting default arguments from __init__:' print class_instance_def.arg1 print class_instance_def.arg2 # создадём экземпляр (или “объект”) класса с аргументами class_instance_changed = thisIsClass('This is first argument', 'This is second argument') print 'nPrinting changed arguments from __init__:' print class_instance_changed.arg1 print class_instance_changed.arg2 # создаём новый подкласс, который наследует свойства # класса thisIsClass class inheritingClass(thisIsClass): # и имеет собственные аргументы arg4 = 'value1' arg5 = 'value2' # создаём нвоый объект класса class_inheriting = inheritingClass() # печатаем собственные аргументы подкласса print 'nPrinting argument from subclass:' print class_inheriting.arg4 print class_inheriting.arg5 # и аргументы, унаследованные от родительского класса print 'nPrinting inherited argument from main class:' print class_inheriting.arg1 print class_inheriting.arg2 # используем унаследованный метод __init__ # родительского класса, что бы переопределить аргументы class_inheriting_with_init = inheritingClass('First changed argument from __init__ of main class', 'Second changed argument from __init__ of main class') print 'nPrinting changed inherited argument from main class:' print class_inheriting_with_init.arg1 print class_inheriting_with_init.arg2

Результат:

$ ./inherit_class.py Printing default arguments from __init__: Default value 1 Default value 2 Printing changed arguments from __init__: This is first argument This is second argument Printing argument from subclass: value1 value2 Printing inherited argument from main class: Default value 1 Default value 2 Printing changed inherited argument from main class: First changed argument from __init__ of main class Second changed argument from __init__ of main class

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

Подклассу можно указать несколько родительских классов — в таком случае он унаследует все их атрибуты:

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

# создаём первый супер-класс class mainClass: arg1 = 'This is argument 1 from class mainClass;' arg2 = 'This is argument 2 from class mainClass;' def ext_1(self): return 'This if method ext_1 from class mainClass.' # создаём объект суперкласса main_class = mainClass() print 'nUsing mainClass:' print main_class.arg1 print main_class.arg2 print main_class.ext_1() # создаём сабкласс # который наследует атрибуты суперкласса mainClass class firstInherit(mainClass): arg3 = 'This is argument 3 from class firstInherit;' arg4 = 'This is argument 4 from class firstInherit;' def ext_2(self): return 'This if method ext_2 from class firstInherit.' first_inherit = firstInherit() print 'nUsing firstInherit:' print first_inherit.arg1 print first_inherit.arg2 print first_inherit.arg3 print first_inherit.arg4 print first_inherit.ext_1() print first_inherit.ext_2() # создаём второй сабкласс # который наследует атрибуты классов mainClass и firstInherit class secondInherit(mainClass, firstInherit): arg5 = 'This is argument 5 from class firstInherit;' arg6 = 'This is argument 6 from class firstInherit;' def ext_3(self): return 'This if method ext_3 from class secondInherit.' second_inherit = secondInherit() print 'nUsing secondInherit:' print second_inherit.arg1 print second_inherit.arg2 print second_inherit.arg3 print second_inherit.arg4 print second_inherit.arg5 print second_inherit.arg6 print second_inherit.ext_1() print second_inherit.ext_2() print second_inherit.ext_3()

Примечание: вместо имён методов ext_N можно было использовать одно и то же имя. Но это уже относится к полиформизму и переопределению методов классов, которые будут рассмотрены позже.

Выполняем скрипт:

$ ./multitype_inheriting.py Using mainClass: This is argument 1 from class mainClass; This is argument 2 from class mainClass; This if method ext_1 from class mainClass. Using firstInherit: This is argument 1 from class mainClass; This is argument 2 from class mainClass; This is argument 3 from class firstInherit; This is argument 4 from class firstInherit; This if method ext_1 from class mainClass. This if method ext_2 from class firstInherit. Using secondInherit: This is argument 1 from class mainClass; This is argument 2 from class mainClass; This is argument 3 from class firstInherit; This is argument 4 from class firstInherit; This is argument 5 from class firstInherit; This is argument 6 from class firstInherit; This if method ext_1 from class mainClass. This if method ext_2 from class firstInherit. This if method ext_3 from class secondInherit.

Поиск атрибутов среди классов

При вызове объекта с атрибутом — интерпретатор бует искать указанный атрибут в описании самого класса, из которого был создан объект; потом — слева направо в указанных ему родительских объектках, потом — в родительских объектах этих родительских объектов (если они есть).

В случае, если аргумент не был найден нигде — будет выдана ошибка:

# создаём первый супер-класс class mainClass: arg1 = 'This is argument 1 from class mainClass;' arg2 = 'This is argument 2 from class mainClass;' def ext_1(self): return 'This if method ext_1 from class mainClass.' # создаём объект суперкласса main_class = mainClass() print 'nUsing mainClass:' print main_class.arg1 # создаём сабкласс # который наследует атрибуты суперкласса mainClass class firstInherit(mainClass): arg3 = 'This is argument 3 from class firstInherit;' arg4 = 'This is argument 4 from class firstInherit;' def ext_2(self): return 'This if method ext_2 from class firstInherit.' first_inherit = firstInherit() print 'nUsing firstInherit:' print first_inherit.arg1 # создаём второй сабкласс # который наследует атрибуты классов mainClass и firstInherit class secondInherit(mainClass, firstInherit): arg5 = 'This is argument 5 from class firstInherit;' arg6 = 'This is argument 6 from class firstInherit;' def ext_3(self): return 'This if method ext_3 from class secondInherit.' second_inherit = secondInherit() print 'nUsing secondInherit:' print second_inherit.arg1 print 'nUsing undefined attribute:' print second_inherit.arg_undef

Результат:

$ ./multitype_inheriting.py Using mainClass: This is argument 1 from class mainClass; Using firstInherit: This is argument 1 from class mainClass; Using secondInherit: This is argument 1 from class mainClass; Using undefined attribute: Traceback (most recent call last): File “./multitype_inheriting.py”, line 44, in print second_inherit.arg_undef AttributeError: secondInherit instance has no attribute 'arg_undef'

Как и в других случаях с классами — для сабклассов можно создавать новые атрибуты:

# создаём первый супер-класс class mainClass: arg1 = 'This is argument 1 from class mainClass;' arg2 = 'This is argument 2 from class mainClass;' def ext_1(self): return 'This if method ext_1 from class mainClass.' # создаём объект суперкласса main_class = mainClass() print 'nUsing mainClass:' print main_class.arg1 # создаём сабкласс # который наследует атрибуты суперкласса mainClass class firstInherit(mainClass): arg3 = 'This is argument 3 from class firstInherit;' arg4 = 'This is argument 4 from class firstInherit;' def ext_2(self): return 'This if method ext_2 from class firstInherit.' first_inherit = firstInherit() print 'nUsing firstInherit:' print first_inherit.arg1 # создаём второй сабкласс # который наследует атрибуты классов mainClass и firstInherit class secondInherit(mainClass, firstInherit): arg5 = 'This is argument 5 from class firstInherit;' arg6 = 'This is argument 6 from class firstInherit;' def ext_3(self): return 'This if method ext_3 from class secondInherit.' second_inherit = secondInherit() print 'nUsing secondInherit:' print second_inherit.arg1 print 'nUsing new attribute:' second_inherit.arg1_new = 'This is new secondInherit class attribute.' print second_inherit.arg1_new

Результат:

$ ./multitype_inheriting.py Using mainClass: This is argument 1 from class mainClass; Using firstInherit: This is argument 1 from class mainClass; Using secondInherit: This is argument 1 from class mainClass; Using new attribute: This is new secondInherit class attribute.

Источник: https://rtfm.co.ua/python-nasledovanie-klassov/

Python. Урок 14. Классы и объекты

Python наследование объектов

Данный урок посвящен объектно-ориентированному программированию в Python. Разобраны такие темы как создание объектов и классов, работа с конструктором, наследование и полиморфизм в Python.

Основные понятия объектно-ориентированного программирования

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

Выделяют три основных “столпа” ООП- это инкапсуляция, наследование и полиморфизм.

Инкапсуляция

Под инкапсуляцией понимается объединение в рамках одной сущности (класса) определенных данных и методов для работы с ними (и не только).

Например, можно определить класс “холодильник”, который будет содержать следующие данные: производитель, объем, количество камер хранения, потребляемая мощность и т.п., и методы: открыть/закрыть холодильник, включить/выключить.

 При этом класс становится новым типом данных в рамках разрабатываемой программы. Можно создавать переменные этого нового типа, такие переменные называются объекты.

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

Под наследованием понимается возможность создания нового класса на базе существующего. Наследование предполагает наличие отношения “является” между классом наследником и классом родителем. При этом класс потомок будет содержать те же атрибуты и методы, что и базовый класс, но при этом его можно (и нужно) расширять через добавление новых методов и атрибутов.

Примером базового класса, демонстрирующего наследование, можно определить класс “автомобиль”, имеющий атрибуты: масса, мощность двигателя, объем топливного бака и методы: завести и заглушить.

У такого класса может быть потомок – “грузовой автомобиль”, он будет содержать те же атрибуты и методы, что и класс “автомобиль”, и дополнительные свойства: количество осей, мощность компрессора и т.

п..

Полиморфизм

Полиморфизм позволяет одинаково обращаться с объектами, имеющими однотипный интерфейс, независимо от внутренней реализации объекта. Например с объектом класса “грузовой автомобиль” можно производить те же операции, что и с объектом класса “автомобиль”, т.к.

первый является наследником второго, при этом обратное утверждение неверно (во всяком случае не всегда). Другими словами полиморфизм предполагает разную реализацию методов с одинаковыми именами.

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

Классы в Python

Создание класса в Python начинается с инструкции class. Вот так будет выглядеть минимальный класс.

class C: pass

Класс состоит из объявления (инструкция class), имени класса (нашем случае это имя C) и тела класса, которое содержит атрибуты и методы (в нашем минимальном классе есть только одна инструкция pass).

Для того чтобы создать объект класса необходимо воспользоваться следующим синтаксисом:

имя_объекта = имя_класса()

Класс может содержать атрибуты и методы. Ниже представлен класс, содержащий атрибуты color (цвет), width (ширина), height (высота).

class Rectangle: color = “green” width = 100 height = 100

Доступ к атрибуту класса можно получить следующим образом.

имя_объекта.атрибут

rect1 = Rectangle() print(rect1.color)

Добавим к нашему классу метод. Метод – это функция находящаяся внутри класса, выполняющая определенную работу, которая, чаще всего, предполагает доступ к атрибутам созданного объекта. Например, нашему классу Rectangle, можно добавить метод, считающий площадь прямоугольника.

Для того, чтобы метод в классе знал, с каким объектом он работает (это нужно для того, чтобы получить доступ к атрибутам: ширина (width) и высота (height)), первым аргументом ему следует передать параметр self, через который он может получить доступ к своим данным.

class Rectangle: color = “green” width = 100 height = 100 def square(self): return self.width * self.height

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

class Rectangle: color = “green” width = 100 height = 100 def square(self): return self.width*self.height rect1 = Rectangle() print(rect1.color) print(rect1.square()) rect2 = Rectangle() rect2.width = 200 rect2.color = “brown” print(rect2.color) print(rect2.square())

Конструктор класса

Конструктор класса позволяет задать определенные параметры объекта при его создании. Таким образом появляется возможность создавать объекты с уже заранее заданными атрибутами. Конструктором класса является метод:

 __init__(self)

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

class Rectangle: def __init__(self, color=”green”, width=100, height=100): self.color = color self.width = width self.height = height def square(self): return self.width * self.height rect1 = Rectangle() print(rect1.color) print(rect1.square()) rect1 = Rectangle(“yellow”, 23, 34) print(rect1.color) print(rect1.square())

P.S.

Если вам интересна тема анализа данных, то мы рекомендуем ознакомиться с библиотекой Pandas. На нашем сайте вы можете найти вводные уроки по этой теме. Все уроки по библиотеке Pandas собраны в книге “Pandas. Работа с данными”.

>

Источник: https://devpractice.ru/python-lesson-14-classes-and-objects/

Программирование на Python: Часть 6. Классы

Python наследование объектов

Сергей Яковлев
02.06.2017 Следите за выходом новых статей этой серии.

Следите за выходом новых статей этой серии.

Мы переходим к одной из самых интересных тем цикла — объектно-ориентированному программированию (ООП) в Python. С точки зрения ООП, класс представляет собой коллекцию данных. Использование классов дает нам прежде всего преимущества абстрактного подхода в программировании.

  1. Полиморфизм: в разных объектах одна и та же операция может выполнять различные функции. Слово «полиморфизм» имеет греческую природу и означает «имеющий многие формы». Простым примером полиморфизма может служить функция count(), выполняющая одинаковое действие для различных типов обьектов: 'abc'.count('a') и [1, 2, 'a'].count('a'). Оператор плюс полиморфичен при сложении чисел и при сложении строк.
  2. Инкапсуляция: можно скрыть ненужные внутренние подробности работы объекта от окружающего мира. Это второй основной принцип абстракции. Он основан на использовании атрибутов внутри класса. Атрибуты могут иметь различные состояния в промежутках между вызовами методов класса, вследствие чего сам объект данного класса также получает различные состояния — state.
  3. Наследование: можно создавать специализированные классы на основе базовых. Это позволяет нам избегать написания повторного кода.
  4. Композиция: объект может быть составным и включать в себя другие объекты.

Объектно-ориентированный подход в программировании подразумевает следующий алгоритм действий.

  1. Описывается проблема с помощью обычного языка с использованием понятий, действий, прилагательных.
  2. На основе понятий формулируются классы.
  3. На основе действий проектируются методы.
  4. Реализуются методы и атрибуты.

Мы получили скелет — объектную модель. На основе этой модели реализуется наследование. Для проверки модели:

  1. пишется так называемый use cases — сценарий возможного поведения модели, где проверяется вся функциональность;
  2. функционал при этом может быть исправлен либо добавлен.

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

Механизм классов языка Python представляет собой смесь механизмов классов C++ и Modula-3. Наиболее важные особенности классов в питоне:

  1. множественное наследование;
  2. производный класс может переопределить любые методы базовых классов;
  3. в любом месте можно вызвать метод с тем же именем базового класса;
  4. все атрибуты класса в питоне по умолчанию являются public, т.е. доступны отовсюду; все методы — виртуальные, т.е. перегружают базовые.

Сегодня мы рассмотрим следующие аспекты объектно-ориентированного программирования.

  1. Что такое класс.
  2. Атрибуты класса.
  3. self.
  4. Наследование.
  5. ООП в действии: пример создания классов.

1. Что такое класс

Класс — это пользовательский тип. Простейшая модель определения класса выглядит следующим образом:

class имя_класса: инструкция 1 . инструкция №

Каждая такая запись генерирует свой объект класса. Отличие от C++ в том, что в плюсах описание класса — это лишь объявление, а в питоне — это создание объекта. Есть также другой тип объекта — инстанс класса, который генерируется при вызове:

инстанс_класса = имя_класса()

Объект класса и инстанс класса — это два разных объекта. Первый генерируется на этапе объявления класса, второй — при вызове имени класса. Объект класса может быть один, инстансов класса может быть сколько угодно.

Инструкция — это, как правило, определение функции. При определении класса создается новое пространство имен и создается объект-класс, который является оболочкой для всех инструкций.

Объекты классов поддерживают два вида операций:

  • доступ к атрибутам;
  • создание экземпляра класса.

2. Атрибуты класса

Атрибуты класса бывают двух видов:

  • атрибуты данных;
  • атрибуты-методы.

Атрибуты данных обычно записываются сверху. Память для атрибутов выделяется в момент их первого присваивания — либо снаружи, либо внутри метода. Методы начинаются со служебного слова def.

Доступ к атрибутам выполняется по схеме obj.attrname.

Пример.

class Simple: u'Простой класс' var = 87 def f(x): return 'Hello world'

Здесь Simple.var и Simple.f — пользовательские атрибуты. Есть также стандартные атрибуты:

Целое число

>>> print Simple.var.__doc__int(x[, base]) -> integer…

Создание экземпляра класса похоже на то, как будто мы делаем вызов функций:

Будет создан пустой объект smpl. Если мы хотим, чтобы при создании выполнялись какие-то действия, нужно определить конструктор, который будет вызываться автоматически:

class Simple: def __init__(self): self.list = []

При создании объекта smpl будет создан пустой список list. Конструктору можно передать аргументы:

class Simple: def __init__(self, count, str): self.list = [] self.count = count self.str = str >>> s = Simple(1,'22')>>> s.count, s.str1 22

Атрибут данных можно сделать приватным (private) — т.е. недоступным снаружи — для этого слева нужно поставить два символа подчеркивания:

class Simple: u'Простой класс с приватным атрибутом' __private_attr = 10 def __init__(self, count, str): self.__private_attr = 20 print self.__private_attr s = Simple(1,'22')print s.__private_attr

Последняя строка вызовет исключение — атрибут __private_attr годен только для внутреннего использования.

Методы необязательно определять внутри тела класса:

def method_for_simple(self, x, y): return x + y class Simple: f = method_for_simple >>> s = Simple()>>> print s.f(1,2)3

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

class Customer: passcustom = Customer()custom.name = 'Вася'custom.salary = 100000

Обычно первый аргумент в имени метода — self. Как говорит автор языка Гвидо Ван Россум, это не более чем соглашение: имя self не имеет абсолютно никакого специального значения.

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

class Simple: def __init__(self): self.list = [] def f1(self): self.list.append(123) def f2(self): self.f1() >>> s = Simple()>>> s.f2()>>> print s.list[123]

Self — это аналог “this” в C++.

4. Наследование

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

Если базовый класс определен не в текущем модуле:

class Derived(module_name.Base):

Разрешение имен атрибутов работает сверху вниз: если атрибут не найден в текущем классе, поиск продолжается в базовом классе, и так далее по рекурсии. Производные классы могут переопределить методы базовых классов — все методы являются в этом смысле виртуальными. Вызвать метод базового класса можно с префиксом:

В питоне существует ограниченная поддержка множественного наследования:

class Derived(Base1,Base2,Base3):

Поиск атрибута производится в следующем порядке:

  1. в Derived;
  2. в Base1, затем рекурсивно в базовых классах Base1;
  3. в Base2, затем рекурсивно в базовых классах Base2
  4. и т.д.

5. Пример

Создадим два класса: Person — хранит общую информацию о людях — имя, профессия, зарплата; класс Manager — специализированный производный класс.

В классе Person мы создадим свою версию для стандартной встроенной функции str, которая есть по умолчанию в любом питоновском классе — для этого она будет иметь префикс с двумя символами подчеркивания слева и справа.

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

# -*- coding: utf-8 -*-class Person: def __init__(self, name, job=None, pay=0): self.name = name self.job = job self.pay = pay def lastName(self): return self.name.split()[-1] def giveRaise(self, percent): self.pay = int(self.pay * (1 + percent)) def __str__(self): return '[Person: %s, %s]' % (self.name, self.pay) class Manager(Person): def __init__(self, name, pay): Person.__init__(self, name, 'mgr', pay) def giveRaise(self, percent, bonus=100): Person.giveRaise(self, percent + bonus)

Создаем первый инстанс класса Person:

>>> ivan = Person('Иван Petrov')

Создаем второй инстанс класса Person:

>>> john = Person('John Sidorov', job='dev', pay=100000)

Вызываем перегруженную функцию __str__;

>>> print(ivan)>>> print(john)

Выводим фамилию:

>>> print(ivan.lastName(), john.lastName())

Начисляем премиальные:

И получаем:

Создаем инстанс класса Manager:

>>> tom = Manager('Tom Jones', 50000)

Начисляем мегапремиальные:

Выводим:

print(tom.lastName())print(tom)

Вывод:

[Person: Иван Petrov, 0][Person: John Sidorov, 100000]('Petrov', 'Sidorov')[Person: John Sidorov, 110000]Jones[Person: Tom Jones, 5055000]

Основные свойства ООП — полиморфизм, наследование, инкапсуляция. Класс — это пользовательский тип, состоящий из методов и атрибутов. Инстанс класса создается путем вызова имени класса как функции с параметрами. Объект состоит из атрибутов и методов. Атрибут — это переменная, метод — это функция.

Отличия метода от функции в том, что у него есть первый параметр — self. Полиморфизм позволяет нам работать с различными типами объектов так, что нам не нужно задумываться о том, к какому типу они принадлежат. Объекты могут скрывать (инкапсулировать) свое внутреннее состояние.

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

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

В следующей статье мы расскажем о работе со специальными методами и атрибутами классов. Код примеров проверялся на версии питона 2.6.

< Предыдущая статья. Следующая статья >

Ресурсы для скачивания

Источник: https://www.ibm.com/developerworks/ru/library/l-python_part_6/

Ооп в python: класс, объект, наследование и конструктор с примерами

Python наследование объектов

От автора: что такое класс? Класс в Python — это логическая группа данных и функций. Он дает возможность создавать структуры данных, которые содержат произвольный контент и, следовательно, легко доступны.

Это можно сравнить с обычным жизненным примером: для любого сотрудника банка, который хочет получить информацию о клиенте в Интернете, следует перейти к классу клиентов, в котором будут перечислены все его атрибуты, такие как детали транзакции, сведения о снятии наличных и депозитах, непогашенный долг и т. д.

В этом руководстве мы рассмотрим:

Как определить классы Python

Как работает наследование

Конструкторы Python

Как определить классы Python

Для определения класса необходимо учитывать следующие моменты.

Шаг 1) В Python классы определяются ключевым словом «Class»

Шаг 2) Внутри классов вы можете определить функции или методы, которые являются частью этого класса

def method1 (self): print “Guru99” def method2 (self,someString): print “Software Testing:” + someString

def method2 (self,someString):    print “Software Testing:” + someString

Здесь мы определили method1, который выводит «Guru99».

Другой метод, который мы определили, это method2, который выводит «Software Testing» + SomeString. SomeString — это переменная, предоставляемая вызывающим методом

Шаг 3) Все в классе указывается с отступом, так же, как код в функции, цикле, операторе if и т. д. Все, что не имеет отступа, не находится в классе:

ПРИМЕЧАНИЕ: об использовании в Python «self»

Аргумент «self» относится к самому объекту. Отсюда и использование слова «self». Таким образом, внутри этого метода self будет ссылаться на конкретный экземпляр этого объекта, с которым работает.

Self — это имя, предпочитаемое соглашением Pythons для обозначения первого параметра методов экземпляра в Python. Это часть синтаксиса Python для доступа к членам объектов

Шаг 4) Создаем объект класса

Шаг 5) Чтобы вызвать метод в классе

c.method1() c.method2(” Testing is fun”)

c.method2(” Testing is fun”)

Обратите внимание, что когда мы вызываем method1 или method2, нам не нужно указывать ключевое слово self. Это автоматически обрабатывается средой исполнения Python.

Среда выполнения Python передает значение «self» при вызове метода экземпляра для экземпляра, независимо от того, предоставили вы его явно или нет

Вам нужно заботиться о других аргументах

Шаг 6) Вот полный код

# Example file for working with classes class myClass(): def method1(self): print(“Guru99”) def method2(self,someString): print(“Software Testing:” + someString) def main(): # exercise the class methods c = myClass () c.method1() c.method2(” Testing is fun”) if __name__== “__main__”: main()

# Example file for working with classes  def method2(self,someString):          print(“Software Testing:” + someString)  # exercise the class methods  c.method2(” Testing is fun”)if __name__== “__main__”:

Как работает наследование

Наследование — это функция, используемая в объектно-ориентированном программировании; оно относится к определению нового класса с небольшими изменениями или без изменения существующего класса.

Новый класс называется производным классом, а тот, который он наследует, называется базовым. Python поддерживает наследование; он также поддерживает множественное наследование.

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

Синтаксис наследования Python

class DerivedClass(BaseClass): body_of_derived_class

class DerivedClass(BaseClass):

Шаг 1) Запустите следующий код

# Example file for working with classes class myClass(): def method1(self): print(“Guru99”) class childClass(myClass): #def method1(self): #myClass.method1(self); #print (“childClass Method1”) def method2(self): print(“childClass method2”) def main(): # exercise the class methods c2 = childClass() c2.method1() #c2.method2() if __name__== “__main__”: main()

# Example file for working with classesclass childClass(myClass):        #print (“childClass Method1”)        print(“childClass method2”)       # exercise the class methodsif __name__== “__main__”:

Обратите внимание, что в childClass метод method1 не определен, но он является производным от родительского myClass. Вывод «Гуру99».

Шаг 2) Раскомментируйте строки № 8 и 10. Запустите код.

Теперь method1 определен в childClass, и вывод «childClass Method» отображается правильно.

Шаг 3) Раскомментируйте строку № 9. Запустите код.

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

ParentClassName.MethodName(self)

ParentClassName.MethodName(self)

В нашем случае мы вызываем myClass.method1(self), и, как ожидается, выводится Guru99

Шаг 4) Раскомментируйте строку № 19. Запустите код.

Вызывается method2 дочернего класса, и «метод childClass2» выводится, как и ожидалось.

Конструкторы Python

Конструктор — это функция класса, которая создает объект с предопределенными значениями. Он начинается с двойного подчеркивания (_). Это метод __init__(). В приведенном ниже примере мы принимаем имя пользователя с помощью конструктора.

class User: name = “” def __init__(self, name): self.name = name def sayHello(self): print(“Welcome to Guru99, ” + self.name) User1 = User(“Alex”) User1.sayHello()

    def __init__(self, name):        print(“Welcome to Guru99, ” + self.name)

Вывод будет: Welcome to Guru99, Alex

Пример Python 2

Приведенные выше коды являются примерами Python 3. Если вы хотите запустить Python 2, рассмотрите следующий код.

# Как определять классы Python # Пример файла для работы с классами class myClass(): def method1(self): print “Guru99” def method2(self,someString): print “Software Testing:” + someString def main(): # методы класса c = myClass () c.method1() c.method2(” Testing is fun”) if __name__== “__main__”: main() #Как работает наследование # Пример файла для работы с классами class myClass(): def method1(self): print “Guru99” class childClass(myClass): #def method1(self): #myClass.method1(self); #print “childClass Method1” def method2(self): print “childClass method2” def main(): # методы класса c2 = childClass() c2.method1() #c2.method2() if __name__== “__main__”: main()

# Как определять классы Python# Пример файла для работы с классами  def method2(self,someString):          print “Software Testing:” + someString  c.method2(” Testing is fun”)if __name__== “__main__”:#Как работает наследование# Пример файла для работы с классамиclass childClass(myClass):        #print “childClass Method1”         print “childClass method2”     if __name__== “__main__”:

Заключение

«Класс» — это логическая группа функций и данных. Класс Python предоставляет все стандартные функции объектно-ориентированного программирования.

Механизм наследования классов

Производный класс, который переопределяет любой метод своего базового класса

Метод может вызывать метод базового класса с тем же именем

Классы Python определяются ключевыми словами «class»

Внутри классов вы можете определить функции или методы, которые являются частью класса

Все в классе имеет отступ, как и код в функции, цикле, операторе if и т. д.

Аргумент self в Python ссылается на сам объект. Self — это имя, предпочитаемое соглашением Pythons для обозначения первого параметра методов экземпляра в Python.

Среда выполнения Python автоматически передаст значение «self» при вызове метода экземпляра в экземпляре, независимо от того, предоставили вы его явно или нет

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

Источник: https://www.guru99.com

Редакция: Команда webformyself.

Источник: https://webformyself.com/oop-v-python-klass-obekt/

Глав-книга
Добавить комментарий