__init__ — первый метод, который вы написали. Но у класса бывают и обычные методы: они описывают, что
экземпляр умеет делать. Так в класс попадает поведение — как upper у строки и append у списка.
Свой метод
Метод объявляется внутри класса, как функция, и первым параметром получает self. Через self метод
читает атрибуты своего экземпляра:
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 мл
Допишите класс Drink: метод label() возвращает строку вида "Капучино — 220 ₽" — название, тире и цену
со знаком рубля.
return f"{self.name} — {self.price} ₽".Заготовка упражнения обновилась с тех пор, как вы сохранили свой код.
Вернуть заготовку? Ваш код в этом упражнении будет удалён.
class Drink:
def __init__(self, name, price):
self.name = name
self.price = price
def label(self):
... # верните строку "Название — цена ₽"Упражнение пока не решено, поэтому для ячеек ниже выполнено эталонное решение — ваш код не изменён.
class Drink:
def __init__(self, name, price):
self.name = name
self.price = price
def label(self):
return f"{self.name} — {self.price} ₽"Метод меняет состояние
Метод может не только вернуть результат, но и изменить атрибуты экземпляра. Набор значений атрибутов называют состоянием объекта: после вызова метода состояние уже другое.
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
Допишите класс CoffeeMachine. У новой машины счётчик чашек cups равен 0. Метод brew(count=1) варит
count чашек — увеличивает счётчик и ничего не возвращает. Метод needs_cleaning() возвращает True, если
с момента создания машина сварила 50 чашек или больше, иначе False.
brew: self.cups = self.cups + count.needs_cleaning сравнивает self.cups с 50 и возвращает результат сравнения; ровно 50 чашек — уже пора чистить.Заготовка упражнения обновилась с тех пор, как вы сохранили свой код.
Вернуть заготовку? Ваш код в этом упражнении будет удалён.
class CoffeeMachine:
def __init__(self):
...
def brew(self, count=1):
...
def needs_cleaning(self):
...Упражнение пока не решено, поэтому для ячеек ниже выполнено эталонное решение — ваш код не изменён.
class CoffeeMachine:
def __init__(self):
self.cups = 0
def brew(self, count=1):
self.cups = self.cups + count
def needs_cleaning(self):
return self.cups >= 50Метод с параметрами
Кроме self, у метода могут быть обычные параметры — и со значениями по умолчанию тоже. При вызове self
не передаётся: его подставит Python.
Допишите класс Bill: Bill(500) хранит сумму счёта в атрибуте amount. Метод with_tip(percent=10)
возвращает сумму с чаевыми, округлённую до целых, и не меняет amount: Bill(500).with_tip() — 550,
Bill(480).with_tip(5) — 504.
with_tip из первого урока, только сумма берётся из self.amount.Заготовка упражнения обновилась с тех пор, как вы сохранили свой код.
Вернуть заготовку? Ваш код в этом упражнении будет удалён.
class Bill:
def __init__(self, amount):
self.amount = amount
def with_tip(self, percent=10):
...Упражнение пока не решено, поэтому для ячеек ниже выполнено эталонное решение — ваш код не изменён.
class Bill:
def __init__(self, amount):
self.amount = amount
def with_tip(self, percent=10):
return round(self.amount * (100 + percent) / 100)Две частые ошибки
Первая — забыть self в параметрах метода. Python всё равно передаст экземпляр первым аргументом, и ему
некуда будет попасть:
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 мл
latte.label + "!"TypeError: unsupported operand type(s) for +: 'method' and 'str'
Что напечатает print(type(latte.label()).__name__)?
type получает его результат — строку. Без скобок было бы method.В menu — три экземпляра Drink из первого упражнения. Сохраните в labels список их строк для меню —
результатов метода label(), по порядку.
[d.label() for d in menu] — со скобками.Заготовка упражнения обновилась с тех пор, как вы сохранили свой код.
Вернуть заготовку? Ваш код в этом упражнении будет удалён.
menu = [Drink("Эспрессо", 150), Drink("Капучино", 220), Drink("Раф", 260)]
labels = ...Упражнение пока не решено, поэтому для ячеек ниже выполнено эталонное решение — ваш код не изменён.
menu = [Drink("Эспрессо", 150), Drink("Капучино", 220), Drink("Раф", 260)]
labels = [d.label() for d in menu]