124 lines
5.3 KiB
Python
124 lines
5.3 KiB
Python
|
"""
|
|||
|
https://stepik.org/lesson/701986/step/6?unit=702087
|
|||
|
|
|||
|
Вы создаете интернет-магазин. Для этого нужно объявить два класса:
|
|||
|
|
|||
|
Shop - класс для управления магазином в целом;
|
|||
|
Product - класс для представления отдельного товара.
|
|||
|
|
|||
|
Объекты класса Shop следует создавать командой:
|
|||
|
>>> shop = Shop("название магазина")
|
|||
|
|
|||
|
В каждом объекте класса Shop должно создаваться локальное свойство:
|
|||
|
goods - список товаров (изначально список пустой).
|
|||
|
|
|||
|
А также в классе объявить методы:
|
|||
|
add_product(self, product) - добавление нового товара в магазин (в конец списка goods);
|
|||
|
remove_product(self, product) - удаление товара product из магазина (из списка goods);
|
|||
|
|
|||
|
Объекты класса Product следует создавать командой:
|
|||
|
p = Product(название, вес, цена)
|
|||
|
>>> p = Product("название", 123, 4.56)
|
|||
|
|
|||
|
В них автоматически должны формироваться локальные атрибуты:
|
|||
|
id - уникальный идентификационный номер товара (генерируется автоматически как целое положительное число от 1 и далее);
|
|||
|
name - название товара (строка);
|
|||
|
weight - вес товара (целое или вещественное положительное число);
|
|||
|
price - цена (целое или вещественное положительное число).
|
|||
|
|
|||
|
В классе Product через магические методы (подумайте какие) осуществить проверку на тип присваиваемых данных локальным атрибутам объектов класса
|
|||
|
(например, id - целое число, name - строка и т.п.). Если проверка не проходит, то генерировать исключение командой:
|
|||
|
raise TypeError("Неверный тип присваиваемых данных.")
|
|||
|
>>> Product("название", "вес", 4.56)
|
|||
|
Traceback (most recent call last):
|
|||
|
...
|
|||
|
TypeError: Неверный тип присваиваемых данных.
|
|||
|
|
|||
|
>>> Product("название", -1, 4.56)
|
|||
|
Traceback (most recent call last):
|
|||
|
...
|
|||
|
TypeError: Неверный тип присваиваемых данных.
|
|||
|
|
|||
|
>>> Product("название", 1, -4.56)
|
|||
|
Traceback (most recent call last):
|
|||
|
...
|
|||
|
TypeError: Неверный тип присваиваемых данных.
|
|||
|
|
|||
|
Также в классе Product с помощью магического(их) метода(ов) запретить удаление локального атрибута id. При попытке это сделать генерировать исключение:
|
|||
|
raise AttributeError("Атрибут id удалять запрещено.")
|
|||
|
>>> del Product("название", 123, 4.56).id
|
|||
|
Traceback (most recent call last):
|
|||
|
...
|
|||
|
AttributeError: Атрибут id удалять запрещено.
|
|||
|
|
|||
|
Пример использования классов (в программе эти строчки не писать):
|
|||
|
shop = Shop("Балакирев и К")
|
|||
|
book = Product("Python ООП", 100, 1024)
|
|||
|
shop.add_product(book)
|
|||
|
shop.add_product(Product("Python", 150, 512))
|
|||
|
for p in shop.goods:
|
|||
|
print(f"{p.name}, {p.weight}, {p.price}")
|
|||
|
|
|||
|
>>> shop = Shop("Балакирев и К")
|
|||
|
>>> book = Product("Python ООП", 100, 1024)
|
|||
|
>>> shop.add_product(book)
|
|||
|
>>> shop.add_product(Product("Python", 150, 512))
|
|||
|
>>> [f"{p.name}, {p.weight}, {p.price}" for p in shop.goods]
|
|||
|
['Python ООП, 100, 1024', 'Python, 150, 512']
|
|||
|
|
|||
|
P.S. На экран ничего выводить не нужно.
|
|||
|
"""
|
|||
|
|
|||
|
from typing import TypeAlias, Union
|
|||
|
|
|||
|
|
|||
|
class Shop:
|
|||
|
def __init__(self, name):
|
|||
|
self.name, self.goods = name, []
|
|||
|
|
|||
|
def add_product(self, product):
|
|||
|
self.goods.append(product)
|
|||
|
|
|||
|
def remove_product(self, product):
|
|||
|
self.goods.remove(product)
|
|||
|
|
|||
|
|
|||
|
Number: TypeAlias = Union[int, float]
|
|||
|
|
|||
|
|
|||
|
class Product:
|
|||
|
__last_id: int = 0
|
|||
|
id: int
|
|||
|
name: str
|
|||
|
weight: Number
|
|||
|
price: Number
|
|||
|
|
|||
|
def __new__(cls, *args, **kwargs):
|
|||
|
cls.__last_id += 1
|
|||
|
return super().__new__(cls)
|
|||
|
|
|||
|
def __init__(self, name: str, weight: Number, price: Number):
|
|||
|
self.id = self.__last_id
|
|||
|
self.name, self.weight, self.price = name, weight, price
|
|||
|
|
|||
|
def __setattr__(self, name: str, value):
|
|||
|
typ = self.__annotations__.get(name, object)
|
|||
|
if not isinstance(value, typ) or (typ is Number and value < 1):
|
|||
|
raise TypeError("Неверный тип присваиваемых данных.")
|
|||
|
super().__setattr__(name, value)
|
|||
|
|
|||
|
def __delattr__(self, name: str) -> None:
|
|||
|
if name == "id":
|
|||
|
raise AttributeError("Атрибут id удалять запрещено.")
|
|||
|
|
|||
|
|
|||
|
def tests():
|
|||
|
...
|
|||
|
|
|||
|
|
|||
|
if __name__ == "__main__":
|
|||
|
import doctest
|
|||
|
|
|||
|
doctest.testmod()
|
|||
|
tests()
|