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()
|