Нашли ошибку?
Скачать чистый
урок 5 из 6≈ 20 минупражнения: 0 из 4

Методы

Метод — функция внутри класса, которая работает с данными своего экземпляра. Метод, который возвращает результат, и метод, который меняет атрибуты; забытый self и вызов без скобок.

Python запустится при первом выполнении

__init__ — первый метод, который вы написали. Но у класса бывают и обычные методы: они описывают, что экземпляр умеет делать. Так в класс попадает поведение — как upper у строки и append у списка.

Свой метод

Метод объявляется внутри класса, как функция, и первым параметром получает self. Через self метод читает атрибуты своего экземпляра:

[ ]Метод label
class Product:
    def __init__(self, name, price, volume):
        self.name = name
        self.price = price
        self.volume = volume

    def label(self):
        return f"{self.name}, {self.volume} мл"


latte = Product("Латте", 220, 300)
tea = Product("Чай", 120, 400)
print(latte.label())
print(tea.label())
Выводсохранённый · нажмите «Выполнить», чтобы получить свой
Латте, 300 мл
Чай, 400 мл

Вызов latte.label() Python превращает в Product.label(latte): экземпляр слева от точки становится аргументом self. Поэтому один и тот же метод у разных экземпляров даёт разный результат — каждый раз self — другой объект.

[ ]Два способа вызвать метод
print(latte.label())
print(Product.label(latte))  # то же самое: latte становится self
Выводсохранённый · нажмите «Выполнить», чтобы получить свой
Латте, 300 мл
Латте, 300 мл
[ ]Упражнение 1Строка для меню решено

Допишите класс Drink: метод label() возвращает строку вида "Капучино — 220 ₽" — название, тире и цену со знаком рубля.

class Drink:
    def __init__(self, name, price):
        self.name = name
        self.price = price

    def label(self):
        ...  # верните строку "Название — цена ₽"

Метод меняет состояние

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

[ ]Продажи круассанов
class Pastry:
    def __init__(self, name, left):
        self.name = name
        self.left = left

    def sell(self, count):
        self.left = self.left - count

    def is_sold_out(self):
        return self.left == 0


croissant = Pastry("Круассан", 5)
croissant.sell(2)
print(croissant.left, croissant.is_sold_out())
croissant.sell(3)
print(croissant.left, croissant.is_sold_out())
Выводсохранённый · нажмите «Выполнить», чтобы получить свой
3 False
0 True
[ ]Упражнение 2Кофемашина решено

Допишите класс CoffeeMachine. У новой машины счётчик чашек cups равен 0. Метод brew(count=1) варит count чашек — увеличивает счётчик и ничего не возвращает. Метод needs_cleaning() возвращает True, если с момента создания машина сварила 50 чашек или больше, иначе False.

class CoffeeMachine:
    def __init__(self):
        ...

    def brew(self, count=1):
        ...

    def needs_cleaning(self):
        ...

Метод с параметрами

Кроме self, у метода могут быть обычные параметры — и со значениями по умолчанию тоже. При вызове self не передаётся: его подставит Python.

[ ]Упражнение 3Счёт с чаевыми решено

Допишите класс Bill: Bill(500) хранит сумму счёта в атрибуте amount. Метод with_tip(percent=10) возвращает сумму с чаевыми, округлённую до целых, и не меняет amount: Bill(500).with_tip() — 550, Bill(480).with_tip(5) — 504.

class Bill:
    def __init__(self, amount):
        self.amount = amount

    def with_tip(self, percent=10):
        ...

Две частые ошибки

Первая — забыть self в параметрах метода. Python всё равно передаст экземпляр первым аргументом, и ему некуда будет попасть:

[ ]Метод без selfошибка: TypeError
class Cookie:
    def __init__(self, name):
        self.name = name

    def label():  # забыли self
        return "печенье"


Cookie("Овсяное").label()
Ошибкасохранённый · нажмите «Выполнить», чтобы получить свой
TypeError: Cookie.label() takes 0 positional arguments but 1 was given

Вторая — забыть скобки. latte.label без скобок — это сам метод, а не результат его вызова:

[ ]Метод без скобок
method = latte.label  # без скобок: сам метод, а не строка
print(type(method).__name__)
print(method())
Выводсохранённый · нажмите «Выполнить», чтобы получить свой
method
Латте, 300 мл
[ ]Метод плюс строкаошибка: TypeError
latte.label + "!"
Ошибкасохранённый · нажмите «Выполнить», чтобы получить свой
TypeError: unsupported operand type(s) for +: 'method' and 'str'
Вопрос

Что напечатает print(type(latte.label()).__name__)?

[ ]Упражнение 4Всё меню строками решено

В menu — три экземпляра Drink из первого упражнения. Сохраните в labels список их строк для меню — результатов метода label(), по порядку.

menu = [Drink("Эспрессо", 150), Drink("Капучино", 220), Drink("Раф", 260)]
labels = ...

Нашли ошибку?