На прошлых уроках мы научились создавать атрибуты-функции внутри классов. Однако, возможно, вы столкнулись с ошибкой при попытке вызвать такую функцию через экземпляр класса. Если вызвать функцию напрямую через класс, никаких проблем не возникнет:
class Car:
def color_car():
print("Красная машина")
Car.color_car() # Всё работает
Но если попробовать сделать то же самое через экземпляр класса, появится ошибка TypeError
:
a = Car()
a.color_car() # Ошибка: TypeError
Проблема возникает из-за того, что мы имеем дело с методом, а не с обычной функцией. Метод — это функция, которая определена внутри класса и обладает несколькими ключевыми особенностями:
Именно это привело к ошибке в предыдущем примере. Когда мы вызываем метод color_car()
через экземпляр a
, Python автоматически передает объект a
в метод. Однако наш метод не ожидал никаких аргументов, что и вызвало исключение.
Чтобы метод работал корректно, нам нужно добавить параметр для получения экземпляра класса, от которого метод вызывается. В следующем примере этот параметр назван self
:
class Car:
def color_car(self):
print(f"Цвет машины: красный")
a = Car()
a.color_car() # Всё работает
!!! Важно
В наших задачах почти всегда нужно использовать аргумент self
при написании обычных методов, ибо потом ваш код проверяется при создании реальных объектов.
Мы можем использовать переданный экземпляр класса для изменения или добавления атрибутов в сам экземпляр. Поскольку объекты, созданные из классов, изменяемы, любые изменения в их атрибутах сохраняются. Вот пример:
class Car:
def set_color(self, color):
instance.color = color
a = Car()
a.set_color("красный")
print(a.color) # Вывод: красный
Теперь метод color_car()
нельзя вызвать напрямую от класса, потому что метод требует аргумент экземпляра. Попытка сделать это приведёт к ошибке:
Car.color_car() # Ошибка: TypeError
Чтобы вызвать метод через класс, нужно передать экземпляр класса вручную:
Car.color_car(a) # Работает
Это эквивалентно вызову a.color_car()
. Этот способ позволяет передавать параметры в метод через класс и обрабатывать их в контексте конкретного экземпляра, не копируя сам метод.
Когда мы добавляем в метод дополнительные параметры, необходимо передавать значения для всех аргументов, кроме первого — экземпляра класса. Экземпляр всё ещё передаётся автоматически, а другие аргументы должны быть заданы явно:
class Car:
def set_color_car(self, color):
self.color = color
a = Car()
a.set_color_car("синий")
print(a.color) # Вывод: синий
Возможно, вам может показаться, что использование методов — это что-то новое и сложное. Однако вы уже сталкивались с методами много раз, например, при работе со списками в Python. Списки в Python — это тоже объекты, а их методы, такие как append()
, remove()
, или sort()
, работают по тем же правилам, что и методы, которые мы создаем в своих классах.
Посмотрим на примеры методов списка:
my_list = [1, 2, 3]
# Используем метод append(), чтобы добавить элемент в список
my_list.append(4)
print(my_list) # Вывод: [1, 2, 3, 4]
# Используем метод remove(), чтобы удалить элемент
my_list.remove(2)
print(my_list) # Вывод: [1, 3, 4]
# Используем метод sort(), чтобы отсортировать список
my_list.sort()
print(my_list) # Вывод: [1, 3, 4]
В этом примере my_list
— это объект класса list
или можно сказать экземпляр класса list
, а методы append()
, remove()
, и sort()
— это методы, которые работают с экземпляром списка, так же как методы, которые мы писали для класса Car
. По сути, когда вы вызываете метод на списке, происходит то же самое, что и в примерах с нашими классами: Python автоматически передает экземпляр списка (my_list
) как первый аргумент метода.
Вот таблица, обобщающая ключевые моменты из лекции о методах и работе с атрибутами экземпляра:
Операция | Синтаксис/Функция | Пример | Вывод |
---|---|---|---|
Определение метода в классе | def method_name(self): | class Car: def color_car(self): ... | — |
Вызов метода через класс | class_name.method_name(self) | Car.color_car(a) | Ошибка: TypeError |
Вызов метода через экземпляр | self.method_name() | a.color_car() | Цвет машины: красный |
Передача экземпляра как аргумент метода | self.method_name(color) | a.set_color("красный") | — |
Изменение атрибута экземпляра | self.attribute = value | a.color = "красный" | — |
Вызов метода с дополнительными аргументами | self.method_name(arg1, arg2) | a.set_color_car("синий") | a.color: синий |
Пример методов списков | list_instance.method_name() | my_list.append(4) | my_list: [1, 2, 3, 4] |
Принцип работы методов списков | list_instance.method_name() | my_list.remove(2) | my_list: [1, 3, 4] |
Работа с методами классов | — | my_list.sort() | my_list: [1, 3, 4] |
Эта таблица обобщает основные аспекты работы с методами в классах, их вызов, передачу аргументов, а также сравнение с методами встроенных объектов, таких как списки.
Так что методы — это вовсе не новая концепция. Вы уже успешно их использовали, просто теперь у вас есть возможность создавать свои собственные методы для работы с объектами, которые вы проектируете в своих классах.