Объектно ориентированное программирование python: Объектно-ориентированное Программирование в Python

Содержание

Объектно-ориентированное Программирование в Python

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

Содержание

Представьте сценарий, где вам нужно разработать болид Формулы-1 используя подход объектно-ориентированного программирования. Первое, что вам нужно сделать — это определить реальные объекты в настоящей гонке Формула-1. Какие аспекты в Формуле-1 обладают определенными характеристиками и могут выполнять ту или иную функцию?

Совет от администрации: Как не потратить каникулы в пустую?

Не качайте курсы которые были слиты в интернете, в них смысла нет и тем более пользы. Лучше инвестируйте в свои знания, выйдите из зимних каникул с новой профессией.

Отвечаем сразу всем кто пишет нам в Telegram "С чего начать изучение Python?". Вот курс, пройдите его!

Получите сертификат!
И вы будете на голову выше остальных кандидатов!

Один из очевидных ответов на этот вопрос — гоночный болид. Условный болид может обладать такими характеристиками как:

  • мощность двигателя;
  • марка;
  • модель;
  • производитель, и т. д.

Соответственно, болид можно запустить, остановить, ускорить, и так далее. Гонщик может быть еще одним объектом в Формуле-1. Гонщик имеет национальность, возраст, пол, и так далее, кроме этого, он обладает таким функционалом, как управление болидом, рулевое управление, переключение передач.

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

Стоит обратить внимание на то, что объектно-ориентированное программирование — не зависящая от языка программирования концепция. Это общая концепция программирования и большинство современных языков, такие как Java, C#, C++ и Python поддерживают объектно-ориентированное программирование.

В этой статье мы разберем подробную инструкцию объектно-ориентированного программирования в Python, но перед этим, рассмотрим некоторые

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

Преимущества и недостатки ООП Python

Рассмотрим несколько основных преимуществ объектно-ориентированного программирования:

  1. Объектно-ориентированное программирование подразумевает повторное использование. Компьютерная программа написанная в форме объектов и классов может быть использована снова в других проектах без повторения кода;
  2. Использование модулярного подхода в объектно-ориентированном программировании позволяет получить читаемый и гибкий код;
  3. В объектно-ориентированном программировании каждый класс имеет определенную задачу. Если ошибка возникнет в одной части кода, вы можете исправить ее локально, без необходимости вмешиваться в другие части кода;
  4. Инкапсуляция данных (которую мы рассмотрим дальше в статье) вносит дополнительный уровень безопасности в разрабатываемую программу с использованием объектно-ориентированного подхода;

Хотя объектно-ориентированное программирование обладает рядом преимуществ, оно также содержит определенные недостатки, некоторые из них находятся в списке ниже:

  1. Для создания объектов необходимо иметь подробное представление о разрабатываемом программном обеспечении;
  2. Не каждый аспект программного обеспечения является лучшим решением для реализации в качестве объекта. Для новичков может быть тяжело прочертить линию в золотой середине;
  3. С тем, как вы вносите все новые и новые классы в код, размер и сложность программы растет в геометрической прогрессии;

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

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

Класс

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

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

Отношение между классом и объектом можно представить более наглядно, взглянув на отношение между машиной и Audi. Да, Audi – это машина. Однако, нет такой вещи, как просто машина. Машина — это абстрактная концепция, которую также реализуют в Toyota, Honda, Ferrari, и других компаниях.

Ключевое слово class используется для создания класса в Python. Название класса следует за ключом class, за которым следует двоеточие. Тело класса начинается с новой строки, с отступом на одну вкладку влево.

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

# Создаем класс Car class Car: # создаем атрибуты класса name = "c200" make = "mercedez" model = 2008 # создаем методы класса def start(self): print ("Заводим двигатель") def stop(self): print ("Отключаем двигатель")

# Создаем класс Car

class Car:

 

    # создаем атрибуты класса

    name = "c200"

    make = "mercedez"

    model = 2008

 

    # создаем методы класса

    def start(self):

        print ("Заводим двигатель")

 

    def stop(self):

        print ("Отключаем двигатель")

В примере выше мы создали класс под названием Car с тремя атрибутами: имя name, марка make и модель model. Наш класс также содержит два метода: start() и stop().

Объекты

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

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

Объект также называется экземпляром. Тем не менее, процесс создания объекта класса называется инициализация. В Python, чтобы создать объект класса, нам просто нужно вписать название класса, с последующими открывающимися и закрывающимися скобками.

Давайте создадим объект класса Car, который мы создали в предыдущем разделе.

# Создаем объект класса Car под названием car_a car_a = Car() # Создаем объект класса Car под названием car_b car_b = Car()

# Создаем объект класса Car под названием car_a

car_a = Car()

 

# Создаем объект класса Car под названием car_b

car_b = Car()

В этом скрипте мы создали два объекта класса Car: car_a и car_b. Чтобы узнать тип созданных нами объектов, мы можем использовать метод type и передать ему названия наших объектов. Выполните следующий код:

В выдаче вы увидите:

Это говорит нам о том, что тип объекта car_b – класс Car.

На данный момент мы создали наш класс и соответствующие ему объекты. Теперь настало время получить доступ к атрибутам класса и вызвать метод класса при помощи объекта класса. Чтобы сделать это, вам нужно только вписать имя объекта, за которым следует оператор точка

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

В этом скрипте мы вызываем метод start() через объект car_b. Выдача будет выглядеть следующим образом:

Заводим двигатель

Заводим двигатель

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

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

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

В предыдущей секции мы разобрались, как создавать объекты класса и как мы можем использовать эти объекты для получения доступа к атрибутам класса

В Python, каждый объект содержит определенные атрибуты по умолчанию и методы в дополнение к определенным пользователем атрибутами. Чтобы посмотреть на все атрибуты и методы объекта, используйте встроенную функцию под названием dir()

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

В выдаче вы увидите следующие атрибуты:

['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'make', 'model', 'name', 'start', 'stop']

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

['__class__',

'__delattr__',

'__dict__',

'__dir__',

'__doc__',

'__eq__',

'__format__',

'__ge__',

'__getattribute__',

'__gt__',

'__hash__',

'__init__',

'__init_subclass__',

'__le__',

'__lt__',

'__module__',

'__ne__',

'__new__',

'__reduce__',

'__reduce_ex__',

'__repr__',

'__setattr__',

'__sizeof__',

'__str__',

'__subclasshook__',

'__weakref__',

'make',

'model',

'name',

'start',

'stop']

Эта встроенная функция очень полезна при изучении атрибутов и функций объекта, особенно при использовании через REPL.

Атрибуты класса против атрибутов экземпляров

Атрибуты могут быть наглядно отнесены к двум типам:

  • атрибуты класса
  • атрибуты экземпляров

Атрибуты класса делятся среди всех объектов класса, в то время как атрибуты экземпляров являются собственностью экземпляра.
Помните, что экземпляр — это просто альтернативное название объекта.

Атрибуты экземпляра объявляются внутри любого метода, в то время как атрибуты класса объявляются вне любого метода.

Следующий пример прояснит эту разницу:

class Car: # создаем атрибуты класса car_count = 0 # создаем методы класса def start(self, name, make, model): print("Двигатель заведен") self.name = name self.make = make self.model = model Car.car_count += 1

class Car:

 

    # создаем атрибуты класса

    car_count = 0

 

    # создаем методы класса

    def start(self, name, make, model):

        print("Двигатель заведен")

        self.name = name

        self.make = make

        self.model = model

        Car.car_count += 1

В указанном выше скрипте мы создаем класс Car с одним атрибутом класса под названием car_count и три атрибута экземпляра под названием name, make и model. Класс содержит один метод start()

, который содержит наши три атрибута экземпляров. Значения атрибутов экземпляров переданы в качестве аргументов методу start(). Внутри метода start, атрибут car_count увеличен на один.

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

Давайте создадим объект класса Car и вызовем метод start().

car_a = Car() car_a.start("Corrola", "Toyota", 2015) print(car_a.name) print(car_a.car_count)

car_a = Car()  

car_a.start("Corrola", "Toyota", 2015)  

print(car_a.name)  

print(car_a.car_count)

В скрипте выше мы вывели название атрибута экземпляра и атрибута класса car_count. В выдаче вы увидите, что атрибут car_count будет иметь значение 1, как показано ниже:

Двигатель заведен Corrola 1

Двигатель заведен

Corrola  

1

Теперь создадим еще один объект класса Car и вызываем метод start().

car_b = Car() car_b.start("City", "Honda", 2013) print(car_b.name) print(car_b.car_count)

car_b = Car()  

car_b.start("City", "Honda", 2013)  

print(car_b.name)  

print(car_b.car_count)

Сейчас если вы выведите значение атрибута car_count, вы увидите 2 в выдаче. Это связано с тем, что атрибут car_count является атрибутом класса и таким образом он разделяется между экземплярами. Объект car_a увеличил свое значение до 1, в то время как car_b увеличил свое значение еще раз, так что итоговое значение равняется 2. Выдача выглядит следующим образом:

Двигатель заведен City 2

Двигатель заведен

City  

2

Методы

Как мы выяснили ранее, в объектно-ориентированном программировании, методы используются для реализации функционалов объекта. В предыдущем разделе мы создали методы start() и stop() для класса Car. До этих пор, мы использовали объекты класса для вызова методов. Однако, есть тип методов, который может быть вызван напрямую при помощи имени класса. Такой метод называется статичным методом.

Статичные методы

Для объявления статического метода, вам нужно указать дескриптор @staticmethod перед названием метода, как показано ниже:

class Car: @staticmethod def get_class_details(): print ("Это класс Car") Car.get_class_details()

class Car:

 

    @staticmethod

    def get_class_details():

        print ("Это класс Car")

 

Car.get_class_details()

В коде выше мы создали класс Car с одним статичным методом get_class_details(). Давайте вызовем этот метод, используя название класса.

Вы можете видеть что нам не нужно создавать экземпляр класса Car для вызова метода get_class_details(), вместо этого мы просто использовали название класса. Стоит упомянуть, что статические методы могут иметь доступ только к атрибутам класса в Python, вы не сможете обратиться к методам через self.

Возврат множественных значений из метода

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

class Square: @staticmethod def get_squares(a, b): return a*a, b*b print(Square.get_squares(3, 5))

class Square:

 

    @staticmethod

    def get_squares(a, b):

        return a*a, b*b

 

print(Square.get_squares(3, 5))

В скрипте выше мы создали класс под названием Square со статичным методом get_squares(). Метод принимает два параметра. Он умножает каждый параметр на себя и возвращает оба результата при помощи оператора return. В выдаче указанного выше скрипта вы увидите квадраты 3 и 5.

Метод str

До этого момента мы выводили атрибуты при помощи метода print(). Посмотрим, что случится, если мы выведем объект класса.

Для этого нам нужно создать простой класс Car с одним методом и попытаться вывести объект класса в консоль. Выполним следующий скрипт:

class Car: # создание методов класса def start(self): print ("Двигатель заведен") car_a = Car() print(car_a)

class Car:

 

    # создание методов класса

    def start(self):

        print ("Двигатель заведен")

 

car_a = Car()  

print(car_a)

В скрипте выше мы создали объект car_a класса Car и вывели его значение на экран. По сути мы относимся к объекту car_a как к строке. Выдача выглядит следующим образом:

<__main__.Car object at 0x000001CCCF4335C0>

<__main__.Car object at 0x000001CCCF4335C0>

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

# создание класса Car class Car: # создание методов класса def __str__(self): return "Car class Object" def start(self): print ("Двигатель заведен") car_a = Car() print(car_a)

# создание класса Car

class Car:

 

    # создание методов класса

    def __str__(self):

        return "Car class Object"

 

    def start(self):

        print ("Двигатель заведен")

 

car_a = Car()  

print(car_a)

В скрипте выше, мы переопределили метод __str__ , предоставив наше собственное определение метода. Теперь, если вы выведите объект car_a, вы увидите сообщение «Car class Object» в консоли. Это сообщение, которое мы внесли в наш пользовательский метод __str__ .

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

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

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

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

class Car: # создание атрибутов класса car_count = 0 # создание методов класса def __init__(self): Car.car_count +=1 print(Car.car_count)

class Car:

 

    # создание атрибутов класса

    car_count = 0

 

    # создание методов класса

    def __init__(self):

        Car.car_count +=1

        print(Car.car_count)

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

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

car_a = Car() car_b = Car() car_c = Car()

car_a = Car()  

car_b = Car()  

car_c = Car()

В выдаче вы увидите выведенное значение 1, 2 и 3, поскольку для каждого объекта значение переменной car_count увеличивается и отображается на экране.

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

Локальные переменные против глобальных

Мы знаем, что есть два типа атрибутов Python: атрибуты экземпляра и атрибуты класса.

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

Локальные переменные

Локальная переменная в классе — это переменная, доступ к которой возможен только внутри блока кода, в котором она определена. Например, если вы определите переменную внутри метода, к нему не удастся получить доступ откуда-либо вне метода. Посмотрим на следующий скрипт:

# создаем класс Car class Car: def start(self): message = "Двигатель заведен" return message

# создаем класс Car

class Car:  

    def start(self):

        message = "Двигатель заведен"

        return message

В скрипте выше мы создали локальную переменную message внутри метода start() класса Car. Теперь создадим объект класса Car и попытаемся получить доступ к локальной переменной message, как показано ниже:

car_a = Car() print(car_a.message)

car_a = Car()  

print(car_a.message)

Скрипт выше приводит к следующей ошибке AttributeError:

AttributeError: 'Car' object has no attribute 'message'

AttributeError: 'Car' object has no attribute 'message'

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

Глобальная переменная

Глобальная переменная определяется вне любого блока, то есть метода, операторов-if, и тому подобное. Доступ к глобальной переменной может быть получен где угодно в классе. Рассмотрим следующий пример.

# создаем класс Car class Car: message1 = "Двигатель заведен" def start(self): message2 = "Автомобиль заведен" return message2 car_a = Car() print(car_a.message1)

# создаем класс Car

class Car:  

    message1 = "Двигатель заведен"

 

    def start(self):

        message2 = "Автомобиль заведен"

        return message2

 

car_a = Car()  

print(car_a.message1)

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

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

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

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

Модификаторы доступа

Модификаторы доступа в Python используются для модификации области видимости переменных по умолчанию. Есть три типа модификаторов доступов в Python ООП:

  1. публичный — public;
  2. приватный — private;
  3. защищенный — protected.

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

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

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

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

class Car: def __init__(self): print ("Двигатель заведен") self.name = "corolla" self.__make = "toyota" self._model = 1999

class Car:  

    def __init__(self):

        print ("Двигатель заведен")

        self.name = "corolla"

        self.__make = "toyota"

        self._model = 1999

Здесь мы создали простой класс Car с конструктором и тремя переменными: name, make, и model (название, марка и модель). Переменная name является публичной, в то время как переменные make и model являются приватными и защищенными, соответственно.

Давайте создадим объект класса Car и попытаемся получить доступ к переменной name. Выполним следующий скрипт:

car_a = Car() print(car_a.name)

car_a = Car()  

print(car_a.name)

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

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

В выдаче мы получим следующее уведомление об ошибке:

AttributeError: 'Car' object has no attribute 'make'

AttributeError: 'Car' object has no attribute 'make'

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

  • Полиморфизм;
  • Наследование;
  • Инкапсуляция.

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

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

В объектно-ориентированном программировании, наследование означает отношение IS-A. Например, болид — это транспорт. Наследование это одна из самых удивительных концепций объектно-ориентированного программирования, так как оно подразумевает повторное использование.

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

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

# Создание класса Vehicle class Vehicle: def vehicle_method(self): print("Это родительский метод из класса Vehicle") # Создание класса Car, который наследует Vehicle class Car(Vehicle): def car_method(self): print("Это метод из дочернего класса")

# Создание класса Vehicle

class Vehicle:  

    def vehicle_method(self):

        print("Это родительский метод из класса Vehicle")

 

# Создание класса Car, который наследует Vehicle

class Car(Vehicle):  

    def car_method(self):

        print("Это метод из дочернего класса")

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

Рассмотрим это на практике и выполним следующий скрипт:

car_a = Car() car_a.vehicle_method() # Вызываем метод родительского класса

car_a = Car()  

car_a.vehicle_method() # Вызываем метод родительского класса

В этом скрипте мы создали объект класса Car вызывали метод vehicle_method() при помощи объекта класса Car. Вы можете обратить внимание на то, что класс Car не содержит ни одного метода vehicle_method(), но так как он унаследовал класс Vehicle, который содержит vehicle_method(), класс Car также будет использовать его. Выдача выглядит следующим образом:

Классы в Python

Всё в Пайтоне является объектами. Это очень расплывчатое утверждение, если до этого вы не изучали программирование вообще. Это означает, что каждый объект в Пайтоне имеет метод и значение по той причине, что все объекты базируются на классе. Класс – это проект объекта. Давайте посмотрим на примере, что это значит:

['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__getslice__', '__gt__', '__hash__', '__init__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_formatter_field_name_split', '_formatter_parser', 'capitalize', 'center', 'count', 'decode', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']

['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__',

'__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__',

'__getslice__', '__gt__', '__hash__', '__init__', '__le__', '__len__', '__lt__',

'__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__',

'__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__',

'_formatter_field_name_split', '_formatter_parser', 'capitalize', 'center', 'count',

'decode', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'index', 'isalnum',

'isalpha', 'isdigit', 'islower', 'isspace', 'istitle', 'isupper', 'join', 'ljust',

'lower', 'lstrip', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition',

'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title',

'translate', 'upper', 'zfill']

В примере мы видим строку, присвоенную переменной х. Это может выглядеть как большой объем, но дело в том, что у этой строки много методов. Если вы используете ключевое слово dir, вы получите список всех методов, которые можно присвоить строке. Мы видим 71 метод! Технически, мы не можем вызвать методы, которые начинаются с подчеркивание, так что это сужает список до 38 методов, но это все еще очень много! Что это значит? Это значит что, строка основана на классе, а переменная х – и есть экземпляр этого класса. В Пайтоне мы можем создавать собственные классы. Начнем!

Создание Класса

Создание класса в Пайтоне – это очень просто. Вот простой пример:

# Python 2.x syntax class Vehicle(object): """docstring""" def __init__(self): """Constructor""" pass

# Python 2.x syntax

 

class Vehicle(object):

    """docstring"""

    

    def __init__(self):

        """Constructor"""

        pass

Этот класс не делает ничего конкретного, тем не менее, это очень хороший инструмент для изучения. Например, чтобы создать класс, мы используем ключевое слово class, за которым следует наименование класса. В Пайтоне, конвенция указывает на то, что наименование класса должно начинаться с заглавной буквы. Далее нам нужно открыть круглые скобки, за которыми следует слово object и закрытые скобки. «object» — то, на чем основан класс, или наследуется от него. Это называется базовым классом или родительским классом. Большая часть классов в Пайтоне основаны на объекте. У классов есть особый метод, под названием __init__.

Этот метод вызывается всякий раз, когда вы создаете (или создаете экземпляр) объект на основе этого класса. Метод __init__ вызывается единожды, и не может быть вызван снова внутри программы. Другое определение метода __init__ — это конструктор, кстати, этот термин редко встречается в Пайтоне. Вы можете подумать, почему я называю это методом, а не функцией? Функция меняет свое имя на «method», когда она находится внутри класса. Обратите внимание на то, что каждый метод должен иметь как минимум один аргумент, что в случае с обычной функцией уже не вяжется. В Python 3 нам не нужно прямо указывать, что мы наследуем у объекта. Вместо этого, мы можем написать это следующим образом:

# Python 3.x syntax class Vehicle: """docstring""" def __init__(self): """Constructor""" pass

# Python 3.x syntax

 

class Vehicle:

    """docstring"""

 

    def __init__(self):

        """Constructor"""

        pass

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

class Vehicle(object): """docstring""" def __init__(self, color, doors, tires): """Constructor""" self.color = color self.doors = doors self.tires = tires def brake(self): """ Stop the car """ return "Braking" def drive(self): """ Drive the car """ return "I'm driving!"

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

class Vehicle(object):

    """docstring"""

 

    def __init__(self, color, doors, tires):

        """Constructor"""

        self.color = color

        self.doors = doors

        self.tires = tires

    

    def brake(self):

        """

        Stop the car

        """

        return "Braking"

    

    def drive(self):

        """

        Drive the car

        """

        return "I'm driving!"

В данном примере мы добавили три атрибута и два метода. Эти три атрибута являются:

self.color = color self.doors = doors self.tires = tires

self.color = color

self.doors = doors

self.tires = tires

Атрибуты описывают автомобиль. У него есть цвет, определенное количество дверей и колес. Также у него есть два метода. Метод описывает, что делает класс. В нашем случае, автомобиль может двигаться и останавливаться. Вы могли заметить, что все методы, включая первый, имеют интересный аргумент, под названием self. Давайте рассмотрим его внимательнее.

Совет от администрации: Как не потратить каникулы в пустую?

Не качайте курсы которые были слиты в интернете, в них смысла нет и тем более пользы. Лучше инвестируйте в свои знания, выйдите из зимних каникул с новой профессией.

Отвечаем сразу всем кто пишет нам в Telegram "С чего начать изучение Python?". Вот курс, пройдите его!

Получите сертификат!
И вы будете на голову выше остальных кандидатов!

Что такое self?

Классам нужен способ, что ссылаться на самих себя. Это не из разряда нарциссичного отношения со стороны класса. Это способ сообщения между экземплярами. Слово self это способ описания любого объекта, буквально. Давайте взглянем на пример, который мне кажется наиболее полезным, когда я сталкиваюсь с чем-то новым и странным:
Добавьте этот код в конец класса, который вы написали ранее и сохраните:

class Vehicle(object): """docstring""" def __init__(self, color, doors, tires): """Constructor""" self.color = color self.doors = doors self.tires = tires def brake(self): """ Stop the car """ return "Braking" def drive(self): """ Drive the car """ return "I'm driving!" if __name__ == "__main__": car = Vehicle("blue", 5, 4) print(car.color) truck = Vehicle("red", 3, 6) print(truck.color)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

class Vehicle(object):

    """docstring"""

 

    def __init__(self, color, doors, tires):

        """Constructor"""

        self.color = color

        self.doors = doors

        self.tires = tires

    

    def brake(self):

        """

        Stop the car

        """

        return "Braking"

    

    def drive(self):

        """

        Drive the car

        """

        return "I'm driving!"

 

if __name__ == "__main__":

    car = Vehicle("blue", 5, 4)

    print(car.color)

    

    truck = Vehicle("red", 3, 6)

    print(truck.color)

Условия оператора if в данном примере это стандартный способ указать Пайтону на то, что вы хотите запустить код, если он выполняется как автономный файл. Если вы импортировали свой модуль в другой скрипт, то код, расположенный ниже проверки if не заработает. В любом случае, если вы запустите этот код, вы создадите два экземпляра класса автомобиля (Vehicle): класс легкового и класс грузового. Каждый экземпляр будет иметь свои собственные атрибуты и методы. Именно по этому, когда мы выводи цвета каждого экземпляра, они и отличаются друг от друга. Причина в том, что этот класс использует аргумент self, чтобы указать самому себе, что есть что. Давайте немного изменим класс, чтобы сделать методы более уникальными:

class Vehicle(object): """docstring""" def __init__(self, color, doors, tires, vtype): """Constructor""" self.color = color self.doors = doors self.tires = tires self.vtype = vtype def brake(self): """ Stop the car """ return "%s braking" % self.vtype def drive(self): """ Drive the car """ return "I'm driving a %s %s!" % (self.color, self.vtype) if __name__ == "__main__": car = Vehicle("blue", 5, 4, "car") print(car.brake()) print(car.drive()) truck = Vehicle("red", 3, 6, "truck") print(truck.drive()) print(truck.brake())

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

class Vehicle(object):

    """docstring"""

    

    def __init__(self, color, doors, tires, vtype):

        """Constructor"""

        self.color = color

        self.doors = doors

        self.tires = tires

        self.vtype = vtype

    

    def brake(self):

        """

        Stop the car

        """

        return "%s braking" % self.vtype

    

    def drive(self):

        """

        Drive the car

        """

        return "I'm driving a %s %s!" % (self.color, self.vtype)

 

 

if __name__ == "__main__":

    car = Vehicle("blue", 5, 4, "car")

    print(car.brake())

    print(car.drive())

 

    truck = Vehicle("red", 3, 6, "truck")

    print(truck.drive())

    print(truck.brake())

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

car braking I'm driving a blue car! I'm driving a red truck! truck braking

car braking

I'm driving a blue car!

I'm driving a red truck!

truck braking

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

Подклассы

Настоящая сила классов становится очевидной, когда вопрос касается подклассов. Вы, возможно, еще не поняли это, но мы уже создали подкласс, когда создавали класс, основанный на объекте. Другими словами, «подклассифицировали» объект. Так как объект – это не очень интересная тема, предыдущие примеры не уделили должного внимания такому сильному инструменту как подкласс. Давайте подклассифицируем наш класс Vehicle и узнаем, как все это работает.

class Car(Vehicle): """ The Car class """ #---------------------------------------------------------------------- def brake(self): """ Override brake method """ return "The car class is breaking slowly!" if __name__ == "__main__": car = Car("yellow", 2, 4, "car") car.brake() 'The car class is breaking slowly!' car.drive() "I'm driving a yellow car!"

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

class Car(Vehicle):

    """

    The Car class

    """

 

    #----------------------------------------------------------------------

    def brake(self):

        """

        Override brake method

        """

        return "The car class is breaking slowly!"

 

 

if __name__ == "__main__":

    car = Car("yellow", 2, 4, "car")

    car.brake()

    'The car class is breaking slowly!'

    car.drive()

    "I'm driving a yellow car!"

В этом примере, мы подклассифицировали класс Vehicle. Вы могли заметить, что мы не использовали методы __init__ и drive. Причина в том, что когда мы хотим сделать из класса подкласс, мы уже имеем все атрибуты и методы, только если мы не переопределяем их. Таким образом, вы могли заметить, что мы переопределяем метод brake и указываем ему делать кое-что другое. Другие методы остаются такими же, какими они и были до этого. Так что, когда вы указываете автомобилю тормозить, он использует оригинальный метод, и мы узнали, что мы водим желтый автомобиль. Когда мы используем значения родительского класса по умолчанию – мы называем это наследование.

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

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

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

Подведем итоги

Классы не такие уж и простые, но они очень и очень полезные и эффективные. С их помощью вы можете использовать переменные в методах, которые делают повторное использование кода намного проще. Я могу порекомендовать взглянуть на исходник Пайтона, для ознакомления с потрясными примерами того, как классы определяются и используются. Теперь, зная, как создавать подклассы, вы можете переопределять параметры родительского класса так, и в тех количествах, как вам угодно. Помните: если вы полностью переопределите его, вы по факту просто создадите новый класс.

Введение в объектно-ориентированное программирование (ООП) на Python

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

Текст публикации представляет собой незначительно сокращенный перевод статьи Дэвида Амоса Object-Oriented Programming (OOP) in Python 3.

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

Например, объект может представлять человека свойствами «имя», «возраст», «адрес» и методами (поведением) «ходьба», «разговор», «дыхание» и «бег». Или электронное письмо описывается свойствами «список получателей», «тема» и «текст», а также методами «добавление вложений» и «отправка».

Иными словами, объектно-ориентированное программирование – это подход для моделирования вещей, а также отношений между вещами. ООП моделирует сущности реального мира в виде программных объектов, с которыми связаны некоторые данные и которые могут выполнять определенные функции.

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

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

Допустим, вы хотите отслеживать работу сотрудников. Необходимо хранить основную информацию о каждом сотруднике: Ф.И.О., возраст, должность, год начала работы. Один из способов это сделать – представить каждого сотрудника в виде списка:

        kirk = ["James Kirk", 34, "Captain", 2265]
spock = ["Spock", 35, "Science Officer", 2254]
mccoy = ["Leonard McCoy", "Chief Medical Officer", 2266]
    

У этого подхода есть ряд проблем.

Во-первых, ухудшается читаемость кода. Чтобы понять, что kirk[0] ссылается на имя сотрудника, нужно перемотать код к объявлению списка.

Во-вторых, возрастает вероятность ошибки. В приведенном коде в списке mccoy не указан возраст, поэтому mccoy[1] вместо возраста вернет "Chief Medical Officer".

Отличный способ сделать такой тип кода более удобным – использовать классы.

Классы и экземпляры

Итак, для создания пользовательских структур данных используются классы. Классы определяют функции, называемые методами класса. Методы описывают поведение – те действия, которые объект, созданный с помощью класса, может выполнять с данными.

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

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

Если класс является планом, то экземпляр – это объект, который построен по этому плану. Он содержит реальные данные, это настоящая собака. Например, 🐕 Майлз, которому недавно исполнилось четыре года.

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

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

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

        class Dog:
    pass
    

Здесь тело класса Dog пока состоит из одного оператора – ключевого слова-заполнителя pass. Заполнитель позволяет запустить этот код без вызова исключений.

Примечание

Имена классов Python принято записывать в нотации CamelCase.

Определим свойства, которые должны иметь все объекты Dog. Для простоты будем описывать собак с помощью клички и возраста.

Свойства, которые должны иметь все объекты класса Dog, определяются в специальном методе с именем __init__(). Каждый раз, когда создается новый объект Dog, __init __() присваивает свойствам объекта значения. То есть __init__() инициализирует каждый новый экземпляр класса.

Методу __init__() можно передать любое количество параметров, но первым параметром всегда является автоматически создаваемая переменная с именем self. Переменная self ссылается на только что созданный экземпляр класса, за счет чего метод __init__() сразу может определить новые атрибуты.

Обновим класс Dog с помощью метода __init__(), который создает атрибуты name и age:

        class Dog:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    

В теле __init__() две инструкции, задействующие переменную self:

  • self.name = name создает атрибут с именем name и присваивает ему значение параметра name.
  • self.age = age создает атрибут age и присваивает ему значение параметра age.

Атрибуты, созданные в __init__() называются атрибутами экземпляра. Значение атрибута экземпляра зависит от конкретного экземпляра класса. Все объекты Dog имеют имя и возраст, но значения атрибутов name и age будут различаться в зависимости от экземпляра Dog.

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

        class Dog:
    # Атрибут класса
    species = "Canis familiaris"

    def __init__(self, name, age):
        self.name = name
        self.age = age
    

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

Теперь, когда у нас есть класс Dog, создадим нескольких собак! 🐶

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

        class Dog:
    pass
    

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

        >>> Dog()
<__main__.Dog at 0x7f6854738150>
    

В памяти компьютера по указанному после at адресу был создан новый объект типа __main__.Dog.

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

        >>> Dog()
<__main__.Dog at 0x7f6854625cd0>
    
        >>> a = Dog()
>>> b = Dog()
>>> a == b
False
    

Хотя a и b являются экземплярами класса Dog, они представляют собой два разных объекта.

Теперь возьмем последнюю рассмотренную нами структуру класса:

        class Dog:
    species = "Canis familiaris"
    def __init__(self, name, age):
        self.name = name
        self.age = age
    

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

        >>> Dog()
[...]

TypeError: __init__() missing 2 required positional arguments: 'name' and 'age'
    

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

        buddy = Dog("Buddy", 9)
miles = Dog("Miles", 4)
    

Но ведь в описании класса __init__() перечислены три параметра – почему в этом примере передаются только два аргумента?

При создании экземпляра Python сам передает новый экземпляр в виде параметра self в метод __init__(). Так что нам нужно беспокоиться только об аргументах name и age.

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

        >>> buddy.name
'Buddy'
>>> buddy.age
9
>>> miles.name
'Miles'
>>> miles.age
4
>>> buddy.species
'Canis familiaris'
>>> miles.species
'Canis familiaris'
    

Одним из важных преимуществ использования классов для организации данных является то, что экземпляры гарантированно имеют ожидаемые атрибуты. У всех экземпляров Dog гарантировано есть атрибуты species, name и age.

Значения атрибутов могут изменяться динамически:

        >>> buddy.age = 10
>>> buddy.age
10
>>> miles.species = "Felis silvestris"
>>> miles.species
'Felis silvestris'
    

Экземпляры не зависят друг от друга. Изменение атрибута класса у одного экземпляра не меняет его у остальных экземпляров:

        >>> buddy.species
'Canis familiaris'
    

Методы экземпляра – это определенные внутри класса функции, которые могут вызываться из экземпляра этого класса. Так же, как и у метода __init__(), первым параметром метода экземпляра всегда является self:

        class Dog:
    species = "Canis familiaris"

    def __init__(self, name, age):
        self.name = name
        self.age = age

    # Метод экземпляра
    def description(self):
        return f"{self.name} is {self.age} years old"

    # Другой метод экземпляра
    def speak(self, sound):
        return f"{self.name} says {sound}"
    

Мы добавили два метода экземпляра, возвращающих строковые значения. Метод description возвращает строку с описанием собаки, метод speak принимает аргумент sound:

        >>> miles = Dog("Miles", 4)
>>> miles.description()
'Miles is 4 years old'
>>> miles.speak("Woof Woof")
'Miles says Woof Woof'
>>> miles.speak("Bow Wow")
'Miles says Bow Wow'
    

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

К примеру, когда вы создаете объект списка, вы можете использовать для отображения функцию print():

        >>> names = ["Fletcher", "David", "Dan"]
>>> print(names)
['Fletcher', 'David', 'Dan']

    

Посмотрим, что произойдет, когда мы попробуем применить print() к объекту miles:

        >>> print(miles)
<__main__.Dog object at 0x7f6854623690>
    

В большинстве практических приложений информация о расположении объекта в памяти не очень полезна. Поведение объекта при взаимодействии с функцией print() можно изменить, определив специальный метод __str__():

        class Dog:
    species = "Canis familiaris"

    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __str__(self):
        return f"{self.name} is {self.age} years old"

    def speak(self, sound):
        return f"{self.name} says {sound}"
    
        >>> miles = Dog("Miles", 4)
>>> print(miles)
Miles is 4 years old
    

Двойные символы подчеркивания в таких методах, как __init__() и __str__() указывают на то, что они имеют предопределенное поведение. Есть множество более сложных методов, которые вы можете использовать для настройки классов в Python, но это тема отдельной публикации.

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

Пример: место для выгула собак

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

Мы можем изменить класс Dog, добавив атрибут breed (англ. порода):

        class Dog:
    species = "Canis familiaris"

    def __init__(self, name, age, breed):
        self.name = name
        self.age = age
        self.breed = breed

    def __str__(self):
        return f"{self.name} is {self.age} years old"

    def speak(self, sound):
        return f"{self.name} says {sound}"
    

Смоделируем несколько псов разных пород:

        miles = Dog("Miles", 4, "Jack Russell Terrier")
buddy = Dog("Buddy", 9, "Dachshund")
jack = Dog("Jack", 3, "Bulldog")
jim = Dog("Jim", 5, "Bulldog")
    

У каждой породы собак поведение несколько отличаются. Например, разные породы по-разному лают: одни говорят «гав», другие делают «вуф». Используя только класс Dog, мы были бы должны указывать строку для аргумента sound метода speak() каждый раз, когда вызываем его в экземпляре Dog:

        >>> buddy.speak("Yap")
'Buddy says Yap'
>>> jim.speak("Woof")
'Jim says Woof'
>>> jack.speak("Woof")
'Jack says Woof'
    

Передавать строку в каждый вызов метод speak() неудобно. Более того, строка, соответствующая звуку, который издает экземпляр, в идеале должна определяться атрибутом breed.

Один из вариантов упростить взаимодействие с классом Dog – создать дочерний класс для каждой породы. Это позволит расширить функциональные возможности наследующих дочерних классов. В том числе можно будет указать аргумент по умолчанию для speak.

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

        class Dog:
    species = "Canis familiaris"

    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __str__(self):
        return f"{self.name} is {self.age} years old"

    def speak(self, sound):
        return f"{self.name} says {sound}"
    

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

        class JackRussellTerrier(Dog):
    pass

class Dachshund(Dog):
    pass

class Bulldog(Dog):
    pass
    

Дочерние классы действуют так же, как родительский класс:

        miles = JackRussellTerrier("Miles", 4)
buddy = Dachshund("Buddy", 9)
jack = Bulldog("Jack", 3)
jim = Bulldog("Jim", 5)
    

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

        >>> miles.species
'Canis familiaris'
>>> buddy.name
'Buddy'
>>> print(jack)
Jack is 3 years old
>>> jim.speak("Woof")
'Jim says Woof'
    

Чтобы определить, к какому классу принадлежит определенный объект, используйте встроенную функцию type():

        >>> type(miles)
__main__.JackRussellTerrier
    

Чтобы определить, является ли miles экземпляром класса Dog, используем встроенную функцию isinstance():

        >>> isinstance(miles, Dog)
True
    

Объекты miles, buddy, jack и jim являются экземплярами Dog, но miles не является экземпляром Bulldog, а jack не является экземпляром Dachshund:

        >>> isinstance(miles, Bulldog)
False
>>> isinstance(jack, Dachshund)
False

    

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

Теперь дадим нашим собакам немного полаять.

Расширяем функциональность родительского класса

Что мы хотим сделать: переопределить в дочерних классах пород метод speak(). Чтобы переопределить метод, определенный в родительском классе, достаточно создать метод с тем же названием в дочернем классе:

        class JackRussellTerrier(Dog):
    def speak(self, sound="Arf"):
        return f"{self.name} says {sound}"
    

Мы переопределили метод speak, добавив для породы JackRussellTerrier значение по умолчанию.

        >>> miles = JackRussellTerrier("Miles", 4)
>>> miles.speak()
'Miles says Arf'
    

Мы по-прежнему можем передать какой-то иной звук:

        >>> miles.speak("Grrr")
'Miles says Grrr'
    

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

        class Dog:
    species = "Canis familiaris"

    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __str__(self):
        return f"{self.name} is {self.age} years old"

    def speak(self, sound):
        return f"{self.name} barks {sound}"
    
        >>> miles = JackRussellTerrier("Miles", 4)
>>> miles.speak()
'Miles says Arf'
    

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

        class JackRussellTerrier(Dog):
    def speak(self, sound="Arf"):
        return super().speak(sound)
    
        >>> miles = JackRussellTerrier("Miles", 4)
>>> miles.speak()
'Miles barks Arf'
    

Здесь при вызове super().speak(sound) внутри класса JackRussellTerrier, Python ищет родительский класс Dog (на это указывает функция super()), и вызывает его метод speak() с переданной переменной sound. Именно поэтому выводится глагол barks, а не says, но с нужным нам звуком Arf, который определен в дочернем классе.

Обратите внимание

В приведенных примерах иерархия классов очень проста. КлассJackRussellTerrierимеет единственный родительский классDog. В реальных примерах иерархия классов может быть довольно сложной.Функцияsuper()делает гораздо больше, чем просто ищет в родительском классе метод или атрибут. В поисках искомого метода или атрибута функция проходит по всей иерархии классов. Поэтому без должной осторожности использованиеsuper()может привести к неожиданным результатам.

Итак, в этом руководстве мы разобрали базовые понятия объектно-ориентированного программирования (ООП) в Python. Мы узнали:

  • в чём отличия классов и экземпляров;
  • как определить класс;
  • как инициализировать экземпляр класса;
  • как определить методы класса и методы экземпляра;
  • как одни классы наследуются от других.

***

Данный материал мы подготовили при поддержке компании GeekBrains — нашего партнёра, предоставляющего помощь в освоении Python. Если вы хотите получит навыки, необходимые для разработки на Python, не тратя лишнее время и силы на поиск знаний, инструментов и привыкание к разному стилю чтения курсов, обратите внимание на факультет Python-разработки. Программа и преподаватели имеют высокие оценки учащихся, а при успешном прохождении курса онлайн-университет гарантирует не только диплом, но и трудоустройство.

Введение в объектно-ориентированное программирование (ООП) на Python

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

Текст публикации представляет собой незначительно сокращенный перевод статьи Дэвида Амоса Object-Oriented Programming (OOP) in Python 3.

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

Например, объект может представлять человека свойствами «имя», «возраст», «адрес» и методами (поведением) «ходьба», «разговор», «дыхание» и «бег». Или электронное письмо описывается свойствами «список получателей», «тема» и «текст», а также методами «добавление вложений» и «отправка».

Иными словами, объектно-ориентированное программирование – это подход для моделирования вещей, а также отношений между вещами. ООП моделирует сущности реального мира в виде программных объектов, с которыми связаны некоторые данные и которые могут выполнять определенные функции.

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

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

Допустим, вы хотите отслеживать работу сотрудников. Необходимо хранить основную информацию о каждом сотруднике: Ф.И.О., возраст, должность, год начала работы. Один из способов это сделать – представить каждого сотрудника в виде списка:

        kirk = ["James Kirk", 34, "Captain", 2265]
spock = ["Spock", 35, "Science Officer", 2254]
mccoy = ["Leonard McCoy", "Chief Medical Officer", 2266]
    

У этого подхода есть ряд проблем.

Во-первых, ухудшается читаемость кода. Чтобы понять, что kirk[0] ссылается на имя сотрудника, нужно перемотать код к объявлению списка.

Во-вторых, возрастает вероятность ошибки. В приведенном коде в списке mccoy не указан возраст, поэтому mccoy[1] вместо возраста вернет "Chief Medical Officer".

Отличный способ сделать такой тип кода более удобным – использовать классы.

Классы и экземпляры

Итак, для создания пользовательских структур данных используются классы. Классы определяют функции, называемые методами класса. Методы описывают поведение – те действия, которые объект, созданный с помощью класса, может выполнять с данными.

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

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

Если класс является планом, то экземпляр – это объект, который построен по этому плану. Он содержит реальные данные, это настоящая собака. Например, 🐕 Майлз, которому недавно исполнилось четыре года.

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

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

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

        class Dog:
    pass
    

Здесь тело класса Dog пока состоит из одного оператора – ключевого слова-заполнителя pass. Заполнитель позволяет запустить этот код без вызова исключений.

Примечание

Имена классов Python принято записывать в нотации CamelCase.

Определим свойства, которые должны иметь все объекты Dog. Для простоты будем описывать собак с помощью клички и возраста.

Свойства, которые должны иметь все объекты класса Dog, определяются в специальном методе с именем __init__(). Каждый раз, когда создается новый объект Dog, __init __() присваивает свойствам объекта значения. То есть __init__() инициализирует каждый новый экземпляр класса.

Методу __init__() можно передать любое количество параметров, но первым параметром всегда является автоматически создаваемая переменная с именем self. Переменная self ссылается на только что созданный экземпляр класса, за счет чего метод __init__() сразу может определить новые атрибуты.

Обновим класс Dog с помощью метода __init__(), который создает атрибуты name и age:

        class Dog:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    

В теле __init__() две инструкции, задействующие переменную self:

  • self.name = name создает атрибут с именем name и присваивает ему значение параметра name.
  • self.age = age создает атрибут age и присваивает ему значение параметра age.

Атрибуты, созданные в __init__() называются атрибутами экземпляра. Значение атрибута экземпляра зависит от конкретного экземпляра класса. Все объекты Dog имеют имя и возраст, но значения атрибутов name и age будут различаться в зависимости от экземпляра Dog.

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

        class Dog:
    # Атрибут класса
    species = "Canis familiaris"

    def __init__(self, name, age):
        self.name = name
        self.age = age
    

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

Теперь, когда у нас есть класс Dog, создадим нескольких собак! 🐶

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

        class Dog:
    pass
    

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

        >>> Dog()
<__main__.Dog at 0x7f6854738150>
    

В памяти компьютера по указанному после at адресу был создан новый объект типа __main__.Dog.

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

        >>> Dog()
<__main__.Dog at 0x7f6854625cd0>
    
        >>> a = Dog()
>>> b = Dog()
>>> a == b
False
    

Хотя a и b являются экземплярами класса Dog, они представляют собой два разных объекта.

Теперь возьмем последнюю рассмотренную нами структуру класса:

        class Dog:
    species = "Canis familiaris"
    def __init__(self, name, age):
        self.name = name
        self.age = age
    

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

        >>> Dog()
[...]

TypeError: __init__() missing 2 required positional arguments: 'name' and 'age'
    

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

        buddy = Dog("Buddy", 9)
miles = Dog("Miles", 4)
    

Но ведь в описании класса __init__() перечислены три параметра – почему в этом примере передаются только два аргумента?

При создании экземпляра Python сам передает новый экземпляр в виде параметра self в метод __init__(). Так что нам нужно беспокоиться только об аргументах name и age.

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

        >>> buddy.name
'Buddy'
>>> buddy.age
9
>>> miles.name
'Miles'
>>> miles.age
4
>>> buddy.species
'Canis familiaris'
>>> miles.species
'Canis familiaris'
    

Одним из важных преимуществ использования классов для организации данных является то, что экземпляры гарантированно имеют ожидаемые атрибуты. У всех экземпляров Dog гарантировано есть атрибуты species, name и age.

Значения атрибутов могут изменяться динамически:

        >>> buddy.age = 10
>>> buddy.age
10
>>> miles.species = "Felis silvestris"
>>> miles.species
'Felis silvestris'
    

Экземпляры не зависят друг от друга. Изменение атрибута класса у одного экземпляра не меняет его у остальных экземпляров:

        >>> buddy.species
'Canis familiaris'
    

Методы экземпляра – это определенные внутри класса функции, которые могут вызываться из экземпляра этого класса. Так же, как и у метода __init__(), первым параметром метода экземпляра всегда является self:

        class Dog:
    species = "Canis familiaris"

    def __init__(self, name, age):
        self.name = name
        self.age = age

    # Метод экземпляра
    def description(self):
        return f"{self.name} is {self.age} years old"

    # Другой метод экземпляра
    def speak(self, sound):
        return f"{self.name} says {sound}"
    

Мы добавили два метода экземпляра, возвращающих строковые значения. Метод description возвращает строку с описанием собаки, метод speak принимает аргумент sound:

        >>> miles = Dog("Miles", 4)
>>> miles.description()
'Miles is 4 years old'
>>> miles.speak("Woof Woof")
'Miles says Woof Woof'
>>> miles.speak("Bow Wow")
'Miles says Bow Wow'
    

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

К примеру, когда вы создаете объект списка, вы можете использовать для отображения функцию print():

        >>> names = ["Fletcher", "David", "Dan"]
>>> print(names)
['Fletcher', 'David', 'Dan']

    

Посмотрим, что произойдет, когда мы попробуем применить print() к объекту miles:

        >>> print(miles)
<__main__.Dog object at 0x7f6854623690>
    

В большинстве практических приложений информация о расположении объекта в памяти не очень полезна. Поведение объекта при взаимодействии с функцией print() можно изменить, определив специальный метод __str__():

        class Dog:
    species = "Canis familiaris"

    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __str__(self):
        return f"{self.name} is {self.age} years old"

    def speak(self, sound):
        return f"{self.name} says {sound}"
    
        >>> miles = Dog("Miles", 4)
>>> print(miles)
Miles is 4 years old
    

Двойные символы подчеркивания в таких методах, как __init__() и __str__() указывают на то, что они имеют предопределенное поведение. Есть множество более сложных методов, которые вы можете использовать для настройки классов в Python, но это тема отдельной публикации.

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

Пример: место для выгула собак

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

Мы можем изменить класс Dog, добавив атрибут breed (англ. порода):

        class Dog:
    species = "Canis familiaris"

    def __init__(self, name, age, breed):
        self.name = name
        self.age = age
        self.breed = breed

    def __str__(self):
        return f"{self.name} is {self.age} years old"

    def speak(self, sound):
        return f"{self.name} says {sound}"
    

Смоделируем несколько псов разных пород:

        miles = Dog("Miles", 4, "Jack Russell Terrier")
buddy = Dog("Buddy", 9, "Dachshund")
jack = Dog("Jack", 3, "Bulldog")
jim = Dog("Jim", 5, "Bulldog")
    

У каждой породы собак поведение несколько отличаются. Например, разные породы по-разному лают: одни говорят «гав», другие делают «вуф». Используя только класс Dog, мы были бы должны указывать строку для аргумента sound метода speak() каждый раз, когда вызываем его в экземпляре Dog:

        >>> buddy.speak("Yap")
'Buddy says Yap'
>>> jim.speak("Woof")
'Jim says Woof'
>>> jack.speak("Woof")
'Jack says Woof'
    

Передавать строку в каждый вызов метод speak() неудобно. Более того, строка, соответствующая звуку, который издает экземпляр, в идеале должна определяться атрибутом breed.

Один из вариантов упростить взаимодействие с классом Dog – создать дочерний класс для каждой породы. Это позволит расширить функциональные возможности наследующих дочерних классов. В том числе можно будет указать аргумент по умолчанию для speak.

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

        class Dog:
    species = "Canis familiaris"

    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __str__(self):
        return f"{self.name} is {self.age} years old"

    def speak(self, sound):
        return f"{self.name} says {sound}"
    

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

        class JackRussellTerrier(Dog):
    pass

class Dachshund(Dog):
    pass

class Bulldog(Dog):
    pass
    

Дочерние классы действуют так же, как родительский класс:

        miles = JackRussellTerrier("Miles", 4)
buddy = Dachshund("Buddy", 9)
jack = Bulldog("Jack", 3)
jim = Bulldog("Jim", 5)
    

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

        >>> miles.species
'Canis familiaris'
>>> buddy.name
'Buddy'
>>> print(jack)
Jack is 3 years old
>>> jim.speak("Woof")
'Jim says Woof'
    

Чтобы определить, к какому классу принадлежит определенный объект, используйте встроенную функцию type():

        >>> type(miles)
__main__.JackRussellTerrier
    

Чтобы определить, является ли miles экземпляром класса Dog, используем встроенную функцию isinstance():

        >>> isinstance(miles, Dog)
True
    

Объекты miles, buddy, jack и jim являются экземплярами Dog, но miles не является экземпляром Bulldog, а jack не является экземпляром Dachshund:

        >>> isinstance(miles, Bulldog)
False
>>> isinstance(jack, Dachshund)
False

    

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

Теперь дадим нашим собакам немного полаять.

Расширяем функциональность родительского класса

Что мы хотим сделать: переопределить в дочерних классах пород метод speak(). Чтобы переопределить метод, определенный в родительском классе, достаточно создать метод с тем же названием в дочернем классе:

        class JackRussellTerrier(Dog):
    def speak(self, sound="Arf"):
        return f"{self.name} says {sound}"
    

Мы переопределили метод speak, добавив для породы JackRussellTerrier значение по умолчанию.

        >>> miles = JackRussellTerrier("Miles", 4)
>>> miles.speak()
'Miles says Arf'
    

Мы по-прежнему можем передать какой-то иной звук:

        >>> miles.speak("Grrr")
'Miles says Grrr'
    

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

        class Dog:
    species = "Canis familiaris"

    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __str__(self):
        return f"{self.name} is {self.age} years old"

    def speak(self, sound):
        return f"{self.name} barks {sound}"
    
        >>> miles = JackRussellTerrier("Miles", 4)
>>> miles.speak()
'Miles says Arf'
    

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

        class JackRussellTerrier(Dog):
    def speak(self, sound="Arf"):
        return super().speak(sound)
    
        >>> miles = JackRussellTerrier("Miles", 4)
>>> miles.speak()
'Miles barks Arf'
    

Здесь при вызове super().speak(sound) внутри класса JackRussellTerrier, Python ищет родительский класс Dog (на это указывает функция super()), и вызывает его метод speak() с переданной переменной sound. Именно поэтому выводится глагол barks, а не says, но с нужным нам звуком Arf, который определен в дочернем классе.

Обратите внимание

В приведенных примерах иерархия классов очень проста. КлассJackRussellTerrierимеет единственный родительский классDog. В реальных примерах иерархия классов может быть довольно сложной.Функцияsuper()делает гораздо больше, чем просто ищет в родительском классе метод или атрибут. В поисках искомого метода или атрибута функция проходит по всей иерархии классов. Поэтому без должной осторожности использованиеsuper()может привести к неожиданным результатам.

Итак, в этом руководстве мы разобрали базовые понятия объектно-ориентированного программирования (ООП) в Python. Мы узнали:

  • в чём отличия классов и экземпляров;
  • как определить класс;
  • как инициализировать экземпляр класса;
  • как определить методы класса и методы экземпляра;
  • как одни классы наследуются от других.

***

Данный материал мы подготовили при поддержке компании GeekBrains — нашего партнёра, предоставляющего помощь в освоении Python. Если вы хотите получит навыки, необходимые для разработки на Python, не тратя лишнее время и силы на поиск знаний, инструментов и привыкание к разному стилю чтения курсов, обратите внимание на факультет Python-разработки. Программа и преподаватели имеют высокие оценки учащихся, а при успешном прохождении курса онлайн-университет гарантирует не только диплом, но и трудоустройство.

Объектно-ориентированное программирование Python 3: классы, экземпляры, методы, объекты

Автор ArseniyDV На чтение 12 мин. Просмотров 8 Опубликовано

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

Например, объектом может выступать человек, свойства которого «возраст», «имя» и методы (поведение) – «дыхание», «разговор», «ходьба» и «бег». Даже электронное письмо описывается свойствами «тема», «список получателей» и «сообщение», а также методами «добавить вложения» и «отправить». Другими словами, ООП – это подход для моделирования вещей и отношений между этими вещами.

Вторая распространенная парадигма – процедурное программирование, структурирующее программу словно рецепт. Эта программа состоит из набора шагов в виде блоков и функций кода, которые поэтапно выполняются для завершения поставленной задачи.

Плюсы и минусы ООП Python

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

  • ООП подразумевает повторное использование. Программа, написанная в форме классов и объектов может применяться повторно в других проектах без необходимости повторения кода.
  • Применение модулярного подхода в ООП позволяет получить гибкий и читаемый код.
  • Каждый класс в объектно-ориентировочном программировании отвечает за определенную задачу. Если ошибка произошла в одной части кода, то ее можно исправить локально, не затрагивая остальные части кода.
  • Инкапсуляция данных вносит дополнительную безопасность в создаваемую программу с применением ООП.

Несмотря на все преимущества объективно-ориентированного программирования, важно знать и о его недостатках, которые мы представили в виде списка:

  1. При создании объектов невозможно обойтись без детального представления о создаваемом программном обеспечении.
  2. Не все аспекты программного обеспечения можно считать подходящим решением для реализации в качестве объекта. Начинающим может быть сложно прочертить линию в золотой середине.
  3. Сложность и размер программы будет расти одновременно с внесением новых классов вход.

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

Основные термины ООП

  1. Класс – прототип для объекта, определенный пользователем, который определяет набор атрибутов, характеризующих любой объект класса. Атрибутами выступают члены данных (переменные класса и экземпляра) и методы, доступ к которым происходит через точечную запись.
  2. Член данных – переменная экземпляра или переменная класса, содержащая данные, которые связаны с классом, а также его объектами.
  3. Переменная класса – переменная, использующаяся всеми экземплярами класса. Они используются не настолько часто, как переменные экземпляра.
  4. Перегрузка функций – назначение больше чем одного поведения конкретной функции. При этом выполняемая операция зависит от типов аргументов или объектов.
  5. Экземпляр – индивидуальный объект, относящийся к определенному классу. К примеру, объект obj принадлежит классу Circle и выступает экземпляром класса Circle.
  6. Переменная экземпляра – переменная, определенная внутри метода и относится только к текущему экземпляру класса.
  7. Перезагрузка оператора – назначение определенному оператору больше чем одной функции.
  8. Instantiation – это создание экземпляра класса.
  9. Объект – уникальный вид функции, определен в определении класса.
  10. Объект – особый экземпляр структуры данных, определяющийся его классом. Объект содержит, как члены данных (переменные класса и экземпляра) и методы.

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

Оператор класса создает новое определение класса. Сразу за ключевым словом class следует имя класса и двоеточие:

classClassName:
‘Optionalclassdocumentationstring’
class_suite

  • Класс имеет строку документации. Получить доступ к ней можно через ClassName .__ doc__ .
  • Class_suite включает все компоненты утверждений, которые определяют член класса, атрибуты данных и функцию.

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

classEmployee:
‘Commonbaseclassforallemployees’
empCount = 0
def__init__(self, name, salary):
self.name = name
self.salary = salary
Employee.empCount += 1
defdisplayCount(self):
print»TotalEmployee %d» % Employee.empCount
defdisplayEmployee(self):
print»Name : «, self.name, «, Salary: «, self.salary

Переменная empCount – переменная класса, значение которой общее для всех экземпляров данного класса. К нему можно получить доступ как Employee.empCount внутри класса, а также за его пределами.

Первый метод __init __ () представляет собой специальный метод, который называют методом инициализации или конструктором класса, который Питон вызывает во время создания нового экземпляра данного класса.

Другие методы класса вы объявляете, как обычные функциями, кроме того, что self является первым аргументом каждого метода. Для вас Python добавляет этот аргумент, чтобы вам не пришлось его включать при вызове методов.

Создание объектов экземпляра

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

«ThiswouldcreatefirstobjectofEmployeeclass»
emp1 = Employee(«Zara», 2000)
«ThiswouldcreatesecondobjectofEmployeeclass»
emp2 = Employee(«Manni», 5000)

Доступ к атрибутам

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

emp1.displayEmployee()
emp2.displayEmployee()
print»TotalEmployee %d» % Employee.empCount

Теперь, соединяя все концепции

#!/usr/bin/python
classEmployee:
‘Commonbaseclassforallemployees’
empCount = 0
def__init__(self, name, salary):
self.name = name
self.salary = salary
Employee.empCount += 1
defdisplayCount(self):
print»TotalEmployee %d» % Employee.empCount
defdisplayEmployee(self):
print»Name : «, self.name, «, Salary: «, self.salary
«ThiswouldcreatefirstobjectofEmployeeclass»
emp1 = Employee(«Zara», 2000)
«ThiswouldcreatesecondobjectofEmployeeclass»
emp2 = Employee(«Manni», 5000)
emp1.displayEmployee()
emp2.displayEmployee()
print»TotalEmployee %d» % Employee.empCount

Результат приведенного выше кода:

Name :Zara ,Salary: 2000
Name :Manni ,Salary: 5000
TotalEmployee2

Можно удалять, изменять или добавлять атрибуты объектов и классов когда угодно:

emp1.age = 7# Addan ‘age’ attribute.
emp1.age = 8# Modify ‘age’ attribute.
del emp1.age # Delete ‘age’ attribute.

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

Для удаления атрибута — Delattr (объект, имя).

Для доступа к атрибуту объекта — GetAttr (объект, имя [, по умолчанию]).

Проверить, существует атрибут или нет — Hasattr (объект, имя).

Установить атрибут — • SetAttr (объект, имя, значение). Если атрибута нет, то он будет создан.

hasattr(emp1, ‘age’)# Returnstrueif ‘age’ attributeexists
getattr(emp1, ‘age’)# Returnsvalueof ‘age’ attribute
setattr(emp1, ‘age’, 8) # Setattribute ‘age’ at 8
delattr(empl, ‘age’)# Deleteattribute ‘age’

Встроенные атрибуты класса

Классы Python поддерживают такие встроенные атрибуты (получить доступ к ним можно, используя оператор точки, так собственно и любой другой атрибут):

  • Имя класса — __name__ .
  • Словарь, которыйсодержитпространствоименикласса — __dict__ .
  • Строка документации класса или нет, в том случае если она не определена -__doc__.
  • Имя модуля, в котором определяется класс __module__ . В интерактивном режиме этот атрибут «__main__».
  • Пустой кортеж, включающий базовые классы, в порядке их появления в списке базовых классов — __bases__.

Давайте попробуем получить доступ к данным атрибутам для приведенного выше класса:

#!/usr/bin/python
classEmployee:
‘Commonbaseclassforallemployees’
empCount = 0
def__init__(self, name, salary):
self.name = name
self.salary = salary
Employee.empCount += 1
defdisplayCount(self):
print»TotalEmployee %d» % Employee.empCount
defdisplayEmployee(self):
print»Name : «, self.name, «, Salary: «, self.salary
print»Employee.__doc__:», Employee.__doc__
print»Employee.__name__:», Employee.__name__
print»Employee.__module__:», Employee.__module__
print»Employee.__bases__:», Employee.__bases__
print»Employee.__dict__:», Employee.__dict__

Результат приведенного выше кода:

Employee.__doc__: Commonbaseclassforallemployees
Employee.__name__: Employee
Employee.__module__: __main__
Employee.__bases__: ()
Employee.__dict__: {‘__module__’: ‘__main__’, ‘displayCount’:
<functiondisplayCountat0xb7c84994>, ’empCount’: 2,
‘displayEmployee’: <functiondisplayEmployeeat0xb7c8441c>,
‘__doc__’: ‘Commonbaseclassforallemployees’,
‘__init__’: <function__init__at0xb7c846bc>}

Уничтожение объектов или сборка мусора

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

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

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

a = 40# Createobject<40>
b = a # Increaseref. countof<40>
c = [b]# Increaseref. countof<40>
del a # Decreaseref. countof<40>
b = 100# Decreaseref. countof<40>
c[0] = -1# Decreaseref. countof<40>

Сборщик мусора уничтожает потерянный экземпляр и освобождает его пространством незаметно. Однако класс может реализовать метод __del __ () (деструктор). Он вызывается тогда, когда экземпляр собирается быть уничтоженным. Данный метод может применяться для очистки всех ресурсов памяти, которые используются экземпляром.

Пример

Данный деструктор __del __ () печатает имя класса экземплятора, идущего на уничтожение:

#!/usr/bin/python
classPoint:
def__init__(self, x=0, y=0):
self.x = x
self.y = y
def__del__(self):
class_name = self.__class__.__name__
printclass_name, «destroyed»
pt1 = Point()
pt2 = pt1
pt3 = pt1
printid(pt1), id(pt2), id(pt3) # printstheidsoftheobejcts
del pt1
del pt2
del pt3

Результат приведенного выше кода:

3083401324 30834013243083401324
Pointdestroyed

Внимание! В идеале нужно определять классы в отдельном файле, после чего перенести их в основной, воспользовавшись оператором import .

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

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

Синтаксис

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

classSubClassName(ParentClass1[, ParentClass2, …]):
‘Optionalclassdocumentationstring’
class_suite

Пример

#!/usr/bin/python
classParent: # defineparentclass
parentAttr = 100
def__init__(self):
print»Callingparentconstructor»
defparentMethod(self):
print’Callingparentmethod’
defsetAttr(self, attr):
Parent.parentAttr = attr
defgetAttr(self):
print»Parentattribute :», Parent.parentAttr
classChild(Parent): # definechildclass
def__init__(self):
print»Callingchildconstructor»
defchildMethod(self):
print’Callingchildmethod’
c = Child()# instanceofchild
c.childMethod()# childcallsitsmethod
c.parentMethod()# callsparent’smethod
c.setAttr(200)# againcallparent’smethod
c.getAttr()# againcallparent’smethod

Результат приведенного выше кода:

Callingchildconstructor
Callingchildmethod
Callingparentmethod
Parentattribute :200

Точно так же можно управлять классом, состоящим из нескольких родительских классов:

class A: # defineyourclass A
…..
class B: # defineyourclass B
…..
classC(A, B): # subclassof A and B
…..

Чтобы проверить отношение классов и экземпляров можно воспользоваться функциями issubclass () или isinstance ().

Isinstance (объект, класс). Функция булева возвращает истину, если OBJ — экземпляр класса Class или выступает экземпляром подкласса класса.

Issubclass ( к югу, вир). Функция булева возвращает истину, если этот подкласс суб является подклассом суперкласса вир.

Переопределяющие методы

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

Пример

#!/usr/bin/python
classParent: # defineparentclass
defmyMethod(self):
print’Callingparentmethod’
classChild(Parent): # definechildclass
defmyMethod(self):
print’Callingchildmethod’
c = Child()# instanceofchild
c.myMethod()# childcallsoverriddenmethod

Результат приведенного выше кода:

Callingchildmethod

Базовые методы перегрузки

Для наглядности мы приведем некоторые общие функции, которые можно переопределить в собственных классах в виде таблицы:

Sr.No. Метод, описание и пример вызова
1 __init__ (self [, args …])

Конструктор (с любыми необязательными аргументами)

Образец вызова: obj = className (args)

2 __del __ (самостоятельно)

Деструктор, удаляет объект

Пример звонка: delobj

3 __repr __ (самостоятельно)

Оцениваемое строковое представление

Пример вызова: repr (obj)

4 __str __ (самостоятельно)

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

Образец вызова: str (obj)

5 __cmp__ (self, x)

Сравнение объектов

Образец вызова: cmp (obj, x)

Операторы перегрузки

Представьте, что вы создали класс Vector для двумерных векторов. Каким будет результат, если добавить оператор «плюс»? Вероятней всего, Питон будет «ругаться». Но решение есть – определите метод метод __add__ в вашем классе для сложения векторов. В таком случае, будет ожидаемый результат:

пример
#!/usr/bin/python
classVector:
def__init__(self, a, b):
self.a = a
self.b = b
def__str__(self):
return’Vector (%d, %d)’ % (self.a, self.b)
def__add__(self,other):
returnVector(self.a + other.a, self.b + other.b)
v1 = Vector(2,10)
v2 = Vector(5,-2)
print v1 + v2

Результат выполненного выше кода:

Vector(7,8)

Скрытие данных

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

пример
#!/usr/bin/python
classJustCounter:
__secretCount = 0
defcount(self):
self.__secretCount += 1
printself.__secretCount
counter = JustCounter()
counter.count()
counter.count()
printcounter.__secretCount

Результат выше приведенного кода:

1
2
Traceback(mostrecentcalllast):
File»test.py», line12, in<module>
printcounter.__secretCount
AttributeError: JustCounterinstancehasnoattribute’__secretCount’

Чтобы выключить имя класса, Питон защищает данных членов, внутреннее изменяя имя. Можно получить доступ к атрибутам object._className__attrName. Если вы замените последнюю строку, то она будет работать следующим образом:

…………………….
printcounter._JustCounter__secretCount

Результат приведенного выше кода:

1
2
2

Сквозной пример по классам

####################################################
## 5. Классы
####################################################
# Чтобы получить класс, мы наследуемся от object.
classHuman(object):
# Атрибут класса. Он разделяется всеми экземплярами данного класса
species = «H. sapiens»
# Обычный конструктор, вызывается при инициализации экземпляра класса
# Учтите, что двойное подчёркивание в начале и в конце имени
# означает объекты и атрибуты, которые применяютсяPython, но находятся
# в пространствах имён, управляемых пользователем.
# Не придумывайте им имена сами.
def__init__(self, name):
# Присваивание значения аргумента атрибуту класса name
self.name = name
# Метод экземпляра. Все методы принимают self в качестве первого аргумента
defsay(self, msg):
return»{name}: {message}».format(name=self.name, message=msg)
# Метод класса разделяется между всеми экземплярами
# Они вызываются с указыванием вызывающего класса в качестве первого аргумента
@classmethod
defget_species(cls):
returncls.species
# Статический метод вызывается без ссылки на класс или экземпляр
@staticmethod
defgrunt():
return»*grunt*»
# Инициализация экземпляра класса
i = Human(name=»Иван»)
print(i.say(«привет»))# Выводит: «Иван: привет»
j = Human(«Пётр»)
print(j.say(«Привет»))# Выводит: «Пётр: привет»
# Вызов метода класса
i.get_species() #=> «H. sapiens»
# Изменение разделяемого атрибута
Human.species = «H. neanderthalensis»
i.get_species() #=> «H. neanderthalensis»
j.get_species() #=> «H. neanderthalensis»
# Вызов статического метода
Human.grunt() #=> «*grunt*»

Насколько сложным для вас оказалось объектно-ориентированное программирование в Python 3? Поделитесь опытом в комментариях.

Объектно-ориентированное программирование в Python | Python

В этой статье мы расскажем об объектно-ориентированном программировании (ООП) в Python и его фундаментальных концепциях.

Python — это мультипарадигмальный язык. Это означает, что он поддерживает различные подходы к программированию.

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

Объект имеет две характеристики:

  • атрибуты;
  • поведение;

Рассмотрим на примере:

Объект – это попугай:

  • имя, возраст, цвет являются атрибутами;
  • пение, танцы — это поведение;

Концепция ООП в Python направлена ​​на создание кода для многократного использования. Эта концепция также известна как DRY (Don’t Repeat Yourself).

В Python концепция ООП реализует несколько принципов:

НаследованиеИспользование элементов из нового класса без изменения существующего класса.
ИнкапсуляцияСкрытие приватных элементов класса от других объектов.
ПолиморфизмКонцепция использования объекта с одинаковым интерфейсом без получения информации о его типе и внутренней структуре.

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

Примером для класса попугая может быть:

Мы используем ключевое слово class для определения пустого класса Parrot . Из класса мы создаем экземпляр – объект определенного класса.

Объект — это экземпляр класса. В определении класса задается только описание объекта. Пример создания объекта класса Parrot:

В данном случае obj является объектом класса Parrot.

Предположим, что у нас есть информация о попугае. Теперь нужно показать, как построить класс и объекты Parrot.

class Parrot:

    # атрибут класса
    species = "bird"

    # атрибут экземпляра
    def __init__(self, name, age):
        self.name = name
        self.age = age

# создаем экземпляр класс Parrot
blu = Parrot("Blu", 10)
woo = Parrot("Woo", 15)

# получаем доступ к атрибутам класса
print("Blu is a {}".format(blu.__class__.species))
print("Woo is also a {}".format(woo.__class__.species))

# получаем доступ к атрибутам экземпляра
print("{} is {} years old".format( blu.name, blu.age))
print("{} is {} years old".format( woo.name, woo.age))

Результат работы программы:

Blu is a bird
Woo is also a bird
Blu is 10 years old
Woo is 15 years old

Сначала мы создаем класс с именем Parrot. Затем мы определяем атрибуты. Они являются характеристикой объекта.

Затем мы создаем экземпляры класса Parrot. В данном случае blu и woo являются ссылками  на новые объекты.

После этого мы получаем доступ к атрибуту класса с помощью __class __.species. Атрибуты класса одинаковы для всех его экземпляров. Точно так же мы получаем доступ к атрибутам экземпляра, используя blu.name и blu.age. Но атрибуты экземпляра уникальны для каждого экземпляра класса.

Методы — это функции, определенные внутри класса. Они используются для определения поведения объекта.

class Parrot:
    
    # атрибуты экземпляра
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    # метод экземпляра
    def sing(self, song):
        return "{} sings {}".format(self.name, song)

    def dance(self):
        return "{} is now dancing".format(self.name)

# создаем экземпляр объекта
blu = Parrot("Blu", 10)

# вызываем методы экземпляра
print(blu.sing("'Happy'"))
print(blu.dance())

Результат работы программы:

Blu sings 'Happy'
Blu is now dancing

В приведенном выше примере мы определяем два метода sing() и dance(). Их называют методами экземпляра, так как они вызываются для экземпляра объекта, то есть для blu.

Наследование — это способ создания нового класса на основе старого. Новый класс является производным классом (дочерним). Существующий класс является базовым классом (родительским).

# родительский класс
class Bird:
    
    def __init__(self):
        print("Bird is ready")

    def whoisThis(self):
        print("Bird")

    def swim(self):
        print("Swim faster")

# дочерний класс
class Penguin(Bird):

    def __init__(self):
        # вызов функции super()
        super().__init__()
        print("Penguin is ready")

    def whoisThis(self):
        print("Penguin")

    def run(self):
        print("Run faster")

peggy = Penguin()
peggy.whoisThis()
peggy.swim()
peggy.run()

Результат работы программы:

Bird is ready
Penguin is ready
Penguin
Swim faster
Run faster

Сначала мы создали два класса: Bird (родительский класс) и Penguin (дочерний класс). Он наследует функции родительского класса. Это прослеживается в методе  swim().

Дочерний класс изменил поведение родительского класса – метод whoisThis(). Также мы расширяем родительский класс, создав новый метод run().

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

Используя ООП в Python, мы можем ограничить доступ к методам и переменным. Это предотвращает изменение данных вне класса. Такой подход называется инкапсуляцией. В Python мы устанавливаем приватный модификатор доступа, используя в качестве префикса подчеркивание одинарное «_» или двойное «_ _» подчеркивание.

class Computer:

    def __init__(self):
        self.__maxprice = 900

    def sell(self):
        print("Selling Price: {}".format(self.__maxprice))

    def setMaxPrice(self, price):
        self.__maxprice = price

c = Computer()
c.sell()

# изменяем цену
c.__maxprice = 1000
c.sell()

# используем функцию сеттера
c.setMaxPrice(1000)
c.sell()

Когда мы запустим эту программу, результат будет следующим:

Selling Price: 900
Selling Price: 900
Selling Price: 1000

Сначала мы определили класс Computer . Затем использовали метод __init__() для хранения значения максимальной стоимости продажи компьютера.

Мы попытались изменить цену, но не смогли, потому что Python рассматривает __maxprice, как приватные атрибуты. Чтобы изменить значение, мы использовали функцию сеттера. То есть, setMaxPrice(), которая принимает цену в качестве параметра.

Полиморфизм — это способность использовать в ООП общий интерфейс для нескольких форм (типов данных).

Предположим, что нужно раскрасить фигуру.  Есть несколько вариантов фигуры (прямоугольник, квадрат, круг). Мы могли бы использовать тот же метод, чтобы закрасить любую форму. Эта концепция называется полиморфизмом.

class Parrot:

    def fly(self):
        print("Parrot can fly")
    
    def swim(self):
        print("Parrot can't swim")

class Penguin:

    def fly(self):
        print("Penguin can't fly")
    
    def swim(self):
        print("Penguin can swim")

# общий интерфейс
def flying_test(bird):
    bird.fly()

#создаем объекты
blu = Parrot()
peggy = Penguin()

# передаем объекты
flying_test(blu)
flying_test(peggy)

Результат:

Parrot can fly
Penguin can't fly

Мы определили два класса: Parrot и Penguin . У каждого из них есть общий метод  fly(), но они разные.

Чтобы реализовать полиморфизм, мы создали общий интерфейс. То есть, функцию flying_test(), которая может принимать любой объект. Затем мы передали объекты blu и peggy в функцию flying_test().

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

 

 

Данная публикация представляет собой перевод статьи «Python Object Oriented Programming» , подготовленной дружной командой проекта Интернет-технологии.ру

объектно-ориентированного программирования (ООП) в Python 3 - Real Python

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

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

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

Из этого руководства вы узнаете, как:

  • Создайте класс , который похож на чертеж для создания объекта
  • Используйте классы для создания новых объектов
  • Модельные системы с наследованием классов

Примечание: Это руководство адаптировано из главы «Объектно-ориентированное программирование (ООП)» в книге Основы Python: Практическое введение в Python 3 .

В книге используется встроенный редактор IDLE Python для создания и редактирования файлов Python и взаимодействия с оболочкой Python, поэтому вы будете время от времени видеть ссылки на IDLE в этом руководстве. Однако у вас не должно возникнуть проблем с запуском примера кода из редактора и среды по вашему выбору.

Что такое объектно-ориентированное программирование в Python?

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

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

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

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

Ключевой вывод состоит в том, что объекты находятся в центре объектно-ориентированного программирования в Python, не только представляя данные, как в процедурном программировании, но также и в общей структуре программы.

Определите класс в Python

Примитивные структуры данных, такие как числа, строки и списки, предназначены для представления простых частей информации, таких как стоимость яблока, название стихотворения или ваши любимые цвета, соответственно. Что, если вы хотите изобразить что-то более сложное?

Например, предположим, что вам нужно

Объектно-ориентированное программирование на Python против Java - Real Python

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

В этой статье сравнивается и противопоставляется поддержка объектно-ориентированного программирования в Python и Java. К концу вы сможете применить свои знания объектно-ориентированного программирования в Python, понять, как переосмыслить свое понимание объектов Java в Python и использовать объекты в стиле Python.

В этой статье вы будете вводить:

  • Создайте базовый класс как на Java, так и на Python
  • Узнайте, как атрибуты объекта работают в Python и Java
  • Сравните и сопоставьте методы Java и функции Python
  • Откройте для себя механизмы наследования и полиморфизма на обоих языках
  • Изучить отражение в Python и Java
  • Применить все в полной реализации класса на обоих языках

Эта статья не является учебником по объектно-ориентированному программированию.Скорее, он сравнивает объектно-ориентированные функции и принципы Python и Java. Читатели должны хорошо знать Java, а также быть знакомы с программированием на Python. Если вы не знакомы с объектно-ориентированным программированием, ознакомьтесь с разделом Введение в объектно-ориентированное программирование (ООП) на Python. Все примеры Python будут работать с Python 3.6 или новее.

Примеры классов в Python и Java

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

Во-первых, предположим, что у вас есть следующее определение класса Car в Java:

  1 вагон общественного класса {
 2 частных цвета строки;
 3 приватная строковая модель;
 4 частных года;
 5
 6 общедоступный автомобиль (цвет строки, модель String, год int)  

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

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

Python - это язык программирования с несколькими парадигмами.Он поддерживает разные подходы к программированию.

Один из популярных подходов к решению проблемы программирования - создание объектов. Это известно как объектно-ориентированное программирование (ООП).

Объект имеет две характеристики:

Возьмем пример:

Попугай может быть объектом, так как имеет следующие свойства:

  • имя, возраст, цвет как атрибуты
  • пение, танец как поведение

Концепция ООП в Python направлена ​​на создание повторно используемого кода.Эта концепция также известна как СУХОЙ (Не повторяйся).

В Python концепция ООП следует некоторым основным принципам:


Класс

Класс - это план объекта.

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

Примером класса попугая может быть:

класс Попугай:
    пройти 

Здесь мы используем ключевое слово class для определения пустого класса Parrot .Из класса мы создаем экземпляры. Экземпляр - это конкретный объект, созданный из определенного класса.


Объект

Объект (экземпляр) - это реализация класса. Когда класс определен, определяется только описание объекта. Следовательно, память или хранилище не выделяются.

Пример объекта класса попугай может быть:

obj = Попугай () 

Здесь obj - это объект класса Parrot .

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

Пример 1: Создание класса и объекта в Python

  класс Попугай:

    # атрибут класса
    разновидности = "птица"

    # атрибут экземпляра
    def __init __ (я, имя, возраст):
        self.name = имя
        self.age = возраст

# создаем экземпляр класса Parrot
blu = Попугай ("Голубой", 10)
woo = Попугай ("Ву", 15)

# доступ к атрибутам класса
print ("Blu is a {}". format (blu .__ class __. разновидности))
print ("Ву тоже {}".формат (ву .__ класс __. виды))

# доступ к атрибутам экземпляра
print ("{} исполнилось {} лет" .format (blu.name, blu.age))
print ("{} {} лет" .format (woo.name, woo.age))  

Выход

  Blu - птица
Ву тоже птица
Блу 10 лет
Ву 15 лет  

В приведенной выше программе мы создали класс с именем Parrot . Затем мы определяем атрибуты. Атрибуты - это характеристика объекта.

Эти атрибуты определены внутри метода __init__ класса.Это метод инициализатора, который запускается первым при создании объекта.

Затем мы создаем экземпляры класса Parrot . Здесь blu и woo - это ссылки (значения) на наши новые объекты.

Мы можем получить доступ к атрибуту класса, используя __class __. Views . Атрибуты класса одинаковы для всех экземпляров класса. Точно так же мы получаем доступ к атрибутам экземпляра, используя blu.name и blu.age . Однако атрибуты экземпляра различны для каждого экземпляра класса.

Чтобы узнать больше о классах и объектах, перейдите в раздел Классы и объекты Python


Методы

Методы - это функции, определенные внутри тела класса. Они используются для определения поведения объекта.

Пример 2: Создание методов на Python

  класс Попугай:
    
    # атрибутов экземпляра
    def __init __ (я, имя, возраст):
        self.name = имя
        self.age = возраст
    
    # метод экземпляра
    def Sing (я, песня):
        верните "{} sings {}".формат (собственное имя, песня)

    def dance (сам):
        return "{} сейчас танцует" .format (self.name)

# создать экземпляр объекта
blu = Попугай ("Голубой", 10)

# вызываем наши методы экземпляра
print (blu.sing ("Счастливый"))
печать (blu.dance ())  

Выход

  Blu поет 'Happy'
Blu сейчас танцует  

В приведенной выше программе мы определяем два метода: sing () и dance () . Они называются методами экземпляра, потому что они вызываются для объекта экземпляра i.e blu .


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

Наследование - это способ создания нового класса для использования деталей существующего класса без его изменения. Вновь сформированный класс является производным классом (или дочерним классом). Точно так же существующий класс является базовым классом (или родительским классом).

Пример 3: Использование наследования в Python

  # родительский класс
класс Bird:
    
    def __init __ (сам):
        print («Птица готова»)

    def whoisThis (я):
        print ("Птица")

    def плавать (сам):
        print («Плыви быстрее»)

# дочерний класс
класс Пингвин (Птица):

    def __init __ (сам):
        # вызов функции super ()
        супер().__в этом__()
        print («Пингвин готов»)

    def whoisThis (я):
        print («Пингвин»)

    def run (self):
        print («Беги быстрее»)

пегги = Пингвин ()
peggy.whoisThis ()
peggy.swim ()
peggy.run ()  

Выход

  Птица готова
Пингвин готов
Пингвин
Плавать быстрее
Беги быстрее  

В приведенной выше программе мы создали два класса, то есть Bird (родительский класс) и Penguin (дочерний класс). Дочерний класс наследует функции родительского класса.Мы можем видеть это из метода swim () .

Опять же, дочерний класс изменил поведение родительского класса. Мы можем видеть это из метода whoisThis () . Кроме того, мы расширяем функции родительского класса, создавая новый метод run () .

Кроме того, мы используем функцию super () внутри метода __init __ () . Это позволяет нам запускать метод __init __ () родительского класса внутри дочернего класса.


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

Используя ООП в Python, мы можем ограничить доступ к методам и переменным. Это предотвращает прямую модификацию данных, которая называется инкапсуляцией. В Python мы обозначаем частные атрибуты, используя в качестве префикса подчеркивание, то есть одиночный _ или двойной __ .

Пример 4: Инкапсуляция данных в Python

  класс Компьютер:

    def __init __ (сам):
        self .__ maxprice = 900

    def sell (self):
        print ("Цена продажи: {}".формат (self .__ maxprice))

    def setMaxPrice (self, price):
        self .__ maxprice = цена

c = Компьютер ()
c.sell ()

# изменить цену
c .__ maxprice = 1000
c.sell ()

# использование функции установки
c.setMaxPrice (1000)
c.sell ()  

Выход

  Цена продажи: 900
Цена продажи: 900
Цена продажи: 1000  

В приведенной выше программе мы определили класс Computer .

Мы использовали метод __init __ () для хранения максимальной цены продажи Computer .Мы пытались изменить цену. Однако мы не можем его изменить, потому что Python обрабатывает __maxprice как частные атрибуты.

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


Полиморфизм

Полиморфизм - это способность (в ООП) использовать общий интерфейс для нескольких форм (типов данных).

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

Пример 5: Использование полиморфизма в Python

  класс Попугай:

    def fly (self):
        print («Попугай умеет летать»)
    
    def плавать (сам):
        print («Попугай не умеет плавать»)

класс Пингвин:

    def fly (self):
        print («Пингвин не умеет летать»)
    
    def плавать (сам):
        print («Пингвин умеет плавать»)

# Общий интерфейс
def flying_test (птица):
    bird.fly ()

#instantiate objects
blu = Попугай ()
пегги = Пингвин ()

# передача объекта
fly_test (blu)
flying_test (пегги)  

Выход

  Попугай умеет летать
Пингвин не умеет летать  

В приведенной выше программе мы определили два класса Parrot и Penguin .У каждого из них есть общий метод fly () . Однако их функции разные.

Чтобы использовать полиморфизм, мы создали общий интерфейс, то есть функцию flying_test () , которая принимает любой объект и вызывает метод объекта fly () . Таким образом, когда мы передали объекты blu и peggy в функции flying_test () , она работала эффективно.


Ключевые моменты, о которых следует помнить:

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

Классы и объекты Python [с примерами]

Объекты и классы Python

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

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

Мы можем думать о классе как об эскизе (прототипе) дома. Он содержит все подробности о этажах, дверях, окнах и т. Д. На основе этих описаний мы строим дом. Дом - это объект.

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


Определение класса в Python

Как и определения функций в Python начинаются с ключевого слова def, определения классов начинаются с ключевого слова class.

Первая строка внутри класса называется docstring и содержит краткое описание класса. Хотя это и не обязательно, это настоятельно рекомендуется.

Вот простое определение класса.

  класс MyNewClass:
    '' 'Это строка документации. Я создал новый класс '' '
    проход  

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

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

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

  класс Человек:
    "Это человек класса"
    возраст = 10

    def greet (сам):
        print ('Привет')


# Вывод: 10
печать (Человек.возраст)

# Вывод: <функция Person.greet>
печать (Person.greet)

# Вывод: 'Это мой второй класс'
print (Person .__ doc__)  

Выход

  10
<функция Person.greet по адресу 0x7fc78c6e8160>
Это человек класса  

Создание объекта в Python

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

Его также можно использовать для создания новых экземпляров объекта (создания экземпляров) этого класса.Процедура создания объекта аналогична вызову функции.

  >>> harry = Person ()  

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

Атрибуты могут быть данными или методом. Методы объекта - это соответствующие функции этого класса.

Это означает, что, поскольку Person.greet является функциональным объектом (атрибутом класса), Person.greet будет объектом метода.

  класс Человек:
    "Это человек класса"
    возраст = 10

    def greet (сам):
        print ('Привет')


# создаем новый объект класса Person
harry = Человек ()

# Вывод: <функция Person.greet>
печать (Person.greet)

# Вывод: <связанный метод Person.greet из <__ main __. Объект Person >>
печать (harry.greet)

# Вызов метода объекта greet ()
# Вывод: Привет
harry.greet ()  

Выход

  <функция Person.приветствовать 0x7fd288e4e160>
<связанный метод Person.greet объекта <__ main __. Person в 0x7fd288e9fa30 >>
Привет  

Вы, возможно, заметили параметр self в определении функции внутри класса, но мы вызвали этот метод просто как harry.greet () без каких-либо аргументов. Это все еще работало.

Это потому, что всякий раз, когда объект вызывает свой метод, сам объект передается в качестве первого аргумента. Итак, harry.greet () переводится в Person.Привет (Гарри) .

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

По этим причинам первым аргументом функции в классе должен быть сам объект. Это условно называется self . Его можно назвать иначе, но мы настоятельно рекомендуем следовать соглашению.

Теперь вы должны быть знакомы с объектом класса, объектом экземпляра, объектом функции, объектом метода и их различиями.


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

Функции класса, начинающиеся с двойного подчеркивания __ , называются специальными функциями, поскольку они имеют особое значение.

Особый интерес представляет функция __init __ () . Эта специальная функция вызывается всякий раз, когда создается новый объект этого класса.

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

  класс ComplexNumber:
    def __init __ (self, r = 0, i = 0):
        self.real = r
        self.imag = я

    def get_data (сам):
        print (f '{self.real} + {self.imag} j')


# Создать новый объект ComplexNumber
num1 = Комплексное число (2, 3)

# Вызвать метод get_data ()
# Вывод: 2 + 3j
num1.get_data ()

# Создаем еще один объект ComplexNumber
# и создайте новый атрибут attr
num2 = Комплексное число (5)
num2.attr = 10

# Вывод: (5, 0, 10)
print ((num2.real, num2.imag, num2.attr))

# но объект c1 не имеет атрибута attr
# AttributeError: объект 'ComplexNumber' не имеет атрибута 'attr'
печать (число1.attr)  

Выход

  2 + 3j
(5, 0, 10)
Отслеживание (последний вызов последний):
  Файл «<строка>», строка 27, в <модуле>
    печать (num1.attr)
AttributeError: объект «ComplexNumber» не имеет атрибута «attr»  

В приведенном выше примере мы определили новый класс для представления комплексных чисел. Он имеет две функции: __init __ () для инициализации переменных (по умолчанию - ноль) и get_data () для правильного отображения числа.

Интересная вещь, которую следует отметить в предыдущем шаге, заключается в том, что атрибуты объекта могут быть созданы на лету. Мы создали новый атрибут attr для объекта num2 и также прочитали его. Но это не создает этот атрибут для объекта num1 .


Удаление атрибутов и объектов

Любой атрибут объекта можно удалить в любое время с помощью оператора del . Попробуйте выполнить следующее в оболочке Python, чтобы увидеть результат.

  >>> число1 = Комплексное число (2,3)
>>> del num1.imag
>>> num1.get_data ()
Отслеживание (последний вызов последний):
...
AttributeError: объект 'ComplexNumber' не имеет атрибута 'imag'

>>> del ComplexNumber.get_data
>>> num1.get_data ()
Отслеживание (последний вызов последний):
...
AttributeError: объект «ComplexNumber» не имеет атрибута «get_data»  

Мы можем даже удалить сам объект, используя оператор del.

  >>> c1 = Комплексное число (1,3)
>>> дель c1
>>> c1
Отслеживание (последний вызов последний):
...
NameError: имя 'c1' не определено  

На самом деле все сложнее. Когда мы выполняем c1 = ComplexNumber (1,3) , в памяти создается новый объект-экземпляр, и имя c1 связывается с ним.

По команде del c1 эта привязка удаляется, а имя c1 удаляется из соответствующего пространства имен. Однако объект продолжает существовать в памяти, и если к нему не привязано другое имя, он автоматически уничтожается.

Это автоматическое уничтожение объектов, на которые нет ссылок, в Python также называется сборкой мусора.

Удаление объектов в Python удаляет привязку имени

Объектно-ориентированное программирование в Python - AskPython

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

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

Парадигма объектно-ориентированного программирования

Классы в Python

Класс - это схема функциональности объекта . Классы используются для создания новых пользовательских структур данных, содержащих произвольные данные.В случае с животным мы могли бы создать класс Animal для отслеживания свойств животного, таких как имя и возраст.

Рассматривайте класс как образец животного с метками. Он содержит все подробности об имени, размере и т. Д. На основе этих описаний мы можем узнать больше о Животном. Здесь Animal - это объект.

Синтаксис:

class class_name:
  проходить
 

Пример:

класс Animal:
  проходить
 

Объекты в Python

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

Синтаксис:

object_name = Class_name (список аргументов)
 

Пример:

класс Dog:

    # атрибут класса
    разновидности = "животное"

    # атрибут экземпляра
    def __init __ (я, имя, возраст):
        self.name = имя
        self.age = возраст

# создать экземпляр класса Dog, т.е. создать объекты
A = Собака ("Голубой", 10)
B = Собака («Ву», 15)

# доступ к атрибутам класса
print ("A - это {}".формат (A .__ класс __. виды))
print ("B - это тоже {}". format (B .__ class __. разновидности))

# доступ к атрибутам экземпляра
print ("{} {} лет" .format (A.name, A.age))
print ("{} {} лет" .format (B.name, B.age))
 

Выход :

 А - животное
B тоже животное
А 10 лет
B 15 лет 

Абстракция данных в Python

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


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

Инкапсуляция относится к связыванию данных и функций в единый блок . Класс представляет инкапсуляцию, поскольку он связывает функциональность и поведение в единый блок и представляет его как объекты.


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

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

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

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

Пример:

# Базовый класс
класс Dog:

    # Атрибут класса
    разновидности = 'млекопитающее'

    # Атрибуты экземпляра
    def __init __ (я, имя, возраст):
        я.name = имя
        self.age = возраст

    # метод экземпляра
    def описание (self):
        return "{} is {} years old" .format (self.name, self.age)

    # метод экземпляра
    def говорить (сам, звук):
        вернуть "{} говорит {}". формат (собственное имя, звук)


# Производный класс (наследуется от класса Dog)
класс Бульдог (Собака):
    def run (self, speed):
        возврат "{} запускает {}". формат (собственное имя, скорость)


# Производный класс наследует атрибуты и
# поведение из родительского класса
Джим = Бульдог («Джим», 12)
печать (Джим.описание())

# Производный класс имеет определенные атрибуты
# а также поведение
print (Jim.run ("медленно"))
 

Выход :

 Джиму 12 лет
Джим медленно бежит 

Полиморфизм в Python

Это явление относится к возможности отображения в нескольких формах.

Допустим, нам нужно раскрасить фигуру. Есть несколько вариантов формы (прямоугольник, квадрат, круг). Однако мы можем использовать тот же метод для раскрашивания любой формы.Эта концепция называется Полиморфизм .

Полиморфизм

Пример:

класс Rectangle:

    def draw (self):
        print ("Рисование прямоугольника.")
    
    
класс Треугольник:

    def draw (self):
        print ("Рисование треугольника.")
    
    

# Общий интерфейс
def draw_shape (Форма):
    Shape.draw ()

#instantiate objects
A = прямоугольник ()
B = Треугольник ()

# передача объекта
draw_shape (A)
draw_shape (B)
 

Выход :

 Рисование прямоугольника.Рисование треугольника. 

Артикул:

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

Введение

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

Рассмотрим сценарий, в котором вам нужно разработать гоночную игру Формулы 1, используя подход объектно-ориентированного программирования.Первое, что вам нужно сделать, это определить объекты реального мира в реальной гонке Формулы 1. Какие объекты в гонке Формулы 1 обладают некоторыми характеристиками и могут выполнять любую функцию? Один из очевидных ответов на этот вопрос - машина. Автомобиль может иметь такие характеристики, как объем двигателя, марка, модель, производитель и т. Д. Точно так же автомобиль можно заводить, останавливать, ускорять и так далее. Водитель может быть другим объектом гонки Формулы-1. У водителя есть национальность, возраст, пол и т. Д., И он может выполнять такие функции, как вождение автомобиля, переключение рулевого управления или переключение трансмиссии.

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

Здесь важно упомянуть, что объектно-ориентированное программирование не зависит от языка. Это общая концепция программирования, и большинство современных языков, таких как Java, C #, C ++ и Python, поддерживают объектно-ориентированное программирование. В этой статье мы увидим подробное введение в объектно-ориентированное программирование на Python, но перед этим мы увидим некоторые преимущества и недостатки объектно-ориентированного программирования.

Плюсы и минусы ООП

Ниже приведены некоторые преимущества объектно-ориентированного программирования:

  • Объектно-ориентированное программирование способствует повторному использованию. Компьютерная программа написана в виде объектов и классов, которые также могут быть повторно использованы в других проектах.
  • Модульный подход, используемый в объектно-ориентированном программировании, приводит к созданию легко обслуживаемого кода.
  • В объектно-ориентированном программировании каждый класс выполняет определенную задачу. Если ошибка возникает в одной части кода, вы можете исправить ее локально, не затрагивая другие части кода.
  • Инкапсуляция данных (которую мы рассмотрим позже в статье) добавляет дополнительный уровень безопасности к программе, разработанной с использованием объектно-ориентированного подхода.

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

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

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

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

Класс

Класс в объектно-ориентированном программировании служит прототипом объекта.Класс можно рассматривать как карту для дома. Вы можете получить представление о том, как выглядит дом, просто взглянув на карту. Однако сам класс - ничто. Например, карта - это не дом, она только объясняет, как будет выглядеть настоящий дом.

Связь между классом и объектом можно понять, посмотрев на связь между автомобилем и Audi. Audi - это на самом деле автомобиль. Однако не существует только автомобиля. Автомобиль - понятие абстрактное, реально оно реализовано в виде Toyota, Ferrari, Honda и т. Д.

Ключевое слово class используется для создания класса в Python. Имя класса следует за ключевым словом class , за которым следует символ двоеточия. Тело класса начинается с новой строки с отступом на одну табуляцию слева.

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

  # Создает класс Car
класс Автомобиль:

    # создать атрибуты класса
    name = "c200"
    make = "mercedez"
    модель = 2008

    # создать методы класса
    def start (self):
        print ("Двигатель запущен")

    def stop (self):
        print ("Двигатель выключен")
  

В приведенном выше примере мы создаем класс с именем Car с тремя атрибутами: name , make и model .Класс car также содержит два метода: start () и stop () .

Объектов

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

Оставить комментарий

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

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