Part 8

Классы и объекты

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

# Lists are declared with square brackets
my_list = [1,2,3]

# Strings are declared with quotation marks
my_string = "Hi there!"

# Dictionaries are declared with curly brackets
my_dict = {"one": 1, "two:": 2}

# Tuples are declared with parentheses
my_tuple = (1,2,3)

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

# we are using the class Fraction from the module fractions
from fractions import Fraction

# create some new fractions
half = Fraction(1,2)

third = Fraction(1,3)

another = Fraction(3,11)

# print these out
print(half)
print(third)
print(another)

# Fractions can be added together, for example
print(half + third)
Пример вывода

1/2 1/3 3/11 5/6

Как видно выше, вызовы методов-конструкторов выглядят немного иначе, чем обычные вызовы методов, с которыми мы сталкивались раньше. Во-первых, они не привязаны ни к какому объекту через точечную запись (ведь вызов конструктора нужен, чтобы сначала создать объект). Имя метода-конструктора также пишется с заглавной буквы: half = Fraction(1,2). Давайте подробнее посмотрим, как создаются объекты, познакомившись с понятием класс.

Класс — это чертеж объекта

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

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

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

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

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

from fractions import Fraction

number = Fraction(2,5)

# Print the numerator
print(number.numerator)

# ...and the denominator
print(number.denominator)
Пример вывода

2 5

Определение класса Fraction содержит объявления переменных numerator и denominator. У каждого объекта, созданного на основе класса, есть собственные конкретные значения, присвоенные этим переменным.

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

from datetime import date

xmas_eve = date(2020, 12, 24)
midsummer = date(2020, 6, 20)

# print only the month attribute of both objects
print(xmas_eve.month)
print(midsummer.month)
Пример вывода

12 6

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

Функции, которые работают с объектами

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

def is_it_weekend(my_date: date):
    weekday = my_date.isoweekday()
    return weekday == 6 or weekday == 7

Эта функция использует метод isoweekday, который определен в классе date, и возвращает целое число: если заданная дата — понедельник, она возвращает 1, если вторник — 2, и так далее.

Использовать приведенную выше функцию можно так:

xmas_eve = date(2020, 12, 24)
midsummer = date(2020, 6, 20)

print(is_it_weekend(xmas_eve))
print(is_it_weekend(midsummer))
Пример вывода

False True

Методы и переменные

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

my_date = date(2020, 12, 24)

# calling a method
weekday = my_date.isoweekday()

# accessing a variable
my_month = my_date.month

print("The day of the week:", weekday)
print("The month:", my_month)
Пример вывода

The day of the week: 4 The month: 12

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

weekday = my_date.isoweekday()

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

weekday =  my_date.isoweekday
print("The day of the week:", weekday)
Пример вывода

The day of the week: <built-in method isoweekday of datetime.date object at 0x10ed66450>

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

my_month = my_date.month

Обратите внимание: здесь нет круглых скобок. Добавление скобок привело бы к ошибке:

my_month = my_date.month()
Пример вывода
Traceback (most recent call last): File "", line 1, in TypeError: 'int' object is not callable
Loading
Loading
Вы дошли до конца этого раздела! Перейти к следующему разделу:

Текущие баллы можно посмотреть в синем индикаторе в правом нижнем углу страницы.