py_stepik/mod_oop/3.1_06_shop.py

124 lines
5.3 KiB
Python
Raw Normal View History

2024-04-10 09:06:47 +00:00
"""
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()