0:04
Давайте усложним немножко наши примеры и добавим классам методы.
Методы это по большому счёту просто функции, которые действуют
в контексте экземпляра класса.
Таким образом так как они действует в контексте экземпляра и
получают ссылку на экземпляр класса, они могут менять его состояние,
обращаясь к атрибутам экземпляра или делать любую полезную
работу, которая нам захочется.
Давайте посмотрим, как создать метод экземпляра и вызвать его.
население
планеты нестабильно, люди рождаются и умирают
поэтому мы создали класс human, у которого есть два атрибута name и age,
имя и возраст
и также у нас есть класс планеты, у которой есть атрибут name
и также атрибут population, который является списком и этот
список будет содержать людей, которые есть на планете.
Вот
здесь мы объявили метод add human, который
является методом экземпляра
и по большому счёту это просто функция, функция, которая принимает
первым аргументом self, это ссылка на экземпляр класса,
а вторым аргументом всё что мы захотим. И так как это обычная функция,
она может принимать сколько угодно аргументов
как позиционных, так и именованных.
В данном случае она принимает один.
Это будет экземпляр класса Human.
Внутри этого метода мы печатаем на экран приветственное сообщение
новому человеку и обновляем атрибут экземпляра population.
Добавляем туда нового человека.
Также внутри методов, так как это просто функция в контексте экземпляра,
мы можем использовать
конструкцию return, чтобы возвращать из них какие-то значения,
но в данном случае нам это не потребовалось.
Давайте посмотрим как этим пользоваться,
мы создаем экземпляр класса Planet, Mars, дальше мы создаем
экземпляр класса Human, даем человеку имя Боб и затем мы
у экземпляра
класса Planet Mars вызываем метод add_human
и передаем в него аргумент,
объект нашего человека.
Таким образом, мы обновляем население планеты и если мы посмотрим
на то что выглядит mars.population, мы видим что действительно
население планеты обновилось. Kак раз то, что мы делали внутри
метода экземпляра add_human.
Ничто не мешает нам из методов вызывать другие методы.
Давайте посмотрим еще на один пример
и убедимся в том, что это действительно возможно,
и как это сделать.
Мы объявляем класс Human, у которого программист предположим решил
сделать атрибут name и age
вот такими, то есть назвать их, начиная с символа нижнего подчёркивания.
Также у этого класса метод экземпляра say,
который также начинается с нижнего подчёркивания,
а ещё два метода say_name и say_нow_old,
которые печатают, сколько человеку лет и какое у него имя.
Что значат эти символы нижнего подчёркивания?
В других языках программирования вы могли встречаться с
protected, рrivate атрибутами то есть механизмами защиты атрибутов,
которые определены внутри класса.
В Python-e такого механизма нет и по большому счёту вы можете
достучаться до любого атрибута,
однако есть такое соглашение, что если атрибут либо метод
названы c символа нижнего подчёркивания, то ими пользоваться
не рекомендуется потому, что в дальнейших версиях
той или иной библиотеки программист, который пишет
может либо отказаться от этих атрибутов или методов, начинающихся
с символа нижнего подчеркивания, либо поменять их поведение
каким-то образом.
Однако у нас есть класс, у которого есть два публичных метода,
say_name и say_how_old, оба эти методы вызывают
приватный метод say.
Посмотрим как этим пользоваться. Мы объявляем
переменным Боб, который является экземпляром класса Human
и дальше мы можем вызывать методы,
которые внутри себя будут вызывать другой метод,
и мы видим что печатается то, что мы хотим.
А вот так вот обращаться к атрибуту экземпляра и методу
экземпляра не рекомендуется
как раз потому что эти
атрибуты и метод начинаются с символа нижнего подчёркивания.
Несмотря на то, что Python предоставляет эту возможность.
Другой концепт, который есть
в реализации классов на Python, это так называемый метод класса
либо classmethod.
Зачем это может быть нужно? Так может получиться, что
вам нужно объявить метод, но
этот метод не привязан к конкретному экземпляру,
но в тоже время он вовлекает класс в свою работу тем или иным образом,
сам класс, то есть сам класс,
которым вы оперируете, лучше всего посмотреть на примере.
Давайте отвлечемся немножко от планет и людей и
посмотрим класс Event, класс, который описывает события.
У этого класса есть описание и дата, когда это событие происходит,
также я переопределил метод str, чтобы когда мы печатали event
на экран выводилось что-то осмысленное.
Посмотрим как им пользоваться.
Мы получаем
текущую дату
используя модуль datetime стандартной библиотеки Python,
и дальше как обычно создаем экземпляр класса Event,
инициализируя его с помощью описания и даты.
6:26
На данном слайде мы добавим нашему классу Event
метод класса.
Зачем?
Давайте рассмотрим такой пример:
повсеместно сейчас распространены мессенджеры, в которых есть
масса умных помощников,
которые предоставляют тот или иной функционал, а пользователи
могут писать им текст
и получать в ответ какой-то ответ,
пользователь пишет
умному помощнику "Привет! Я хочу добавить такое-то событие
на такую то дату",
умный помощник принимает этот ввод пользователя,
анализирует его на серверной стороне и добавляет событие
в календарь пользователя.
Давайте посмотрим как это можно было бы сделать на Python-е.
А у нас есть все тот же класс Event,
но мы добавили ему метод from_string,
который обернули декоратором classmethod.
Сlassmethod - это встроенный объект,
вам не нужно его ниоткуда импортировать,
данный декоратор делает метод
методом класса,
в отличие от метода экземпляра,
метод класса первым аргументом принимает не ссылку на конкретный
экземпляр класса, а сам класс непосредственно, то есть
в данном случае это будет класс Event, а не конкретный экземпляр.
Внутри этого метода мы из пользовательского ввода,
в данном случае это user_input,
каким-то образом выделяем дату, которую пользователь хочет
создать и описание события,
на примере мы сделали это с помощью
коротких функций-заглушек, которые из строки выделяют дату и описание,
на самом деле - это нетривиальные задачи.
Для того чтобы анализировать пользовательский ввод в таком ключе,
требуется специальные библиотеки или даже есть для этого сервисы.
Это не так просто, но мы для простоты
возвращаем просто какое-то описание и какую-то дату.
Получив описание и дату
мы можем проинициализировать класс и вернуть
экземпляр класса события на основе вот той строки,
которую нам передал пользователь
и получить экземпляр класса Event
и как-то дальше с ним оперировать, добавить его в календарь.
Таким образом classmethod может быть полезен как например
альтернативный конструктор вашего класса.
Давайте посмотрим, как им пользоваться.
Когда после того как мы всё это объявили, у нас есть класс Event
и мы можем вызвать метод класса from_string и передать в него строку.
Произойдёт
анализ этой строки и в результате нам вернётся экземпляр класса Event
и мы видим, что у нас всё получилось,
на экран вывелось как раз правильное описание события.
Возможно вам сейчас не очень очевидно, зачем нужны класс-методы,
но это становится более очевидным, когда появляется наследование.
Класс-метод принимает на вход класс и этот класс будет всегда тем, который,
внутри которого этот класс-метод описан
и вы относительно этого класса можете не только его
как-то инициализировать и вернуть, но вы также можете обращаться
к атрибутам класса,
делать всё что угодно, что вы можете сделать с классом.
Внутри стандартной библиотеки класс- методы тоже активно используются.
И например, вы знаете, что dict - это класс. И соответственно
у dict-а, у словаря, есть метод fromkeys. Это как раз метод класса, который
принимая какой-то итерабельный объект,
возвращает нам проинициализированный словарь.
В данном случае мы передали в него строку и получили словарь,
где ключ - это элeменты последовательности в строке.
В этом видео мы научились объявлять и работать с методами экземпляров,
а также посмотрели на методы класса, которые в отличие от
методов экземпляров принимают первым аргументом не ссылку
на конкретный экземпляр класса, а сам класс непосредственно.
В следующем видео мы посмотрим на другие особенности реализации
классов в Python-e и посмотрим на статический метод и на property.