题目
入门
正所谓能跑得起来运行不出错、达到作业要求就好了
# 创建一个商品类,有:管理人员姓名、密码、商品编号、商品名称、进货单价、销售单价、销售折扣、库存共8个属性,
# 方法有:身份验证、修改商品名称、修改进货价、修改单价、修改折扣、修改库存、显示商品基础信息。
# 使用这个类创建三个对象。
# 要求:当执行:修改商品名称、修改进货价、修改单价、修改折扣、修改库存方法的时候需要身份验证。
# 显示商品显示除了进货价外的其他属性。
class Goods:
def __init__(self, username: str, password: str,
goods_id: str, goods_name: str, purchase_price: float,
sale_price: float, discount: float, stock: int):
self.username = username # 管理人员姓名
self.password = password # 管理人员密码
self.goods_id = goods_id # 商品编号
self.goods_name = goods_name # 商品名称
self.purchase_price = purchase_price # 进货单价 单位:元
self.sale_price = sale_price # 销售单价 单位:元
self.discount = discount # 销售折扣 0.0~1.0
self.stock = stock # 库存 单位:件
# 额外变量:
self.isLogin = False # 是否登录
def login(self, username: str, password: str) -> bool:
"""身份验证,需要管理员验证"""
if self.username == username and self.password == password:
self.isLogin = True
return True
else:
# 登录失败就重置登录状态
self.isLogin = False
return False
def modify_goods_name(self, goods_name: str):
"""修改商品名称,需要管理员验证"""
if not self.isLogin:
return False
# 商品名称不能为None和空
if goods_name is not None and goods_name != "":
self.goods_name = goods_name
return True
self.goods_name = goods_name
return True
def modify_purchase_price(self, purchase_price: float):
"""修改进货价,需要管理员验证"""
if not self.isLogin:
return False
# 进货价不能为负数
if purchase_price >= 0:
self.purchase_price = purchase_price
return True
else:
return False
def modify_sale_price(self, sale_price: float):
"""修改单价,需要管理员验证"""
if not self.isLogin:
return False
# 单价不能为负数
if sale_price >= 0:
self.sale_price = sale_price
return True
else:
return False
def modify_discount(self, discount: float):
"""修改折扣,需要管理员验证"""
if not self.isLogin:
return False
# 折扣范围 0.0~1.0
if 0.0 <= discount <= 1.0:
self.discount = discount
return True
else:
return False
def modify_stock(self, stock: int):
"""修改库存,需要管理员验证"""
if not self.isLogin:
return False
# 库存不能为负数
if stock >= 0:
self.stock = stock
return True
else:
return False
def show_info(self):
"""显示商品基础信息"""
print(
f"商品编号:{self.goods_id},商品名称:{self.goods_name},销售单价:{self.sale_price}元,销售折扣:{self.discount},库存:{self.stock}件")
def show_all_info(self):
"""显示商品所有信息,需要管理员验证"""
if not self.isLogin:
return False
print(
f"商品编号:{self.goods_id},商品名称:{self.goods_name},进货单价:{self.purchase_price}元,销售单价:{self.sale_price}元,销售折扣:{self.discount},库存:{self.stock}件")
return True
if __name__ == '__main__':
goodsList = [
Goods("admin1", "123456", "001", "苹果", 5.0, 10.0, 0.8, 100),
Goods("admin2", "123456", "002", "香蕉", 2.0, 5.0, 0.9, 200),
Goods("admin3", "123456", "003", "橘子", 3.0, 6.0, 0.8, 300)
]
goodsIdList = [goods.goods_id for goods in goodsList]
menuList = ["1.显示商品信息", "2.修改商品名称", "3.修改进货价", "4.修改单价", "5.修改折扣", "6.修改库存",
"7.显示商品的所有信息", "8.退出/切换商品"]
while True:
# 打印商品信息
print("\n商品信息如下:")
for goods in goodsList:
goods.show_info()
print("——————————————————————")
# 选择商品
goods_id = input("请输入你要操作的商品的编号(输入q则退出):")
if goods_id == "":
print(" - 您没有输入商品编号!")
continue
if goods_id == "q":
print(" - 退出程序!")
break
if goods_id not in goodsIdList:
print(" - 您输入的商品编号不存在!")
continue
# 选择商品
goodsIndex = goodsIdList.index(goods_id) # 获取商品索引
goods = goodsList[goodsIndex] # 获取商品对象
print(f" - 您选择的商品是:{goods.goods_name}")
# 选择操作
while True:
print("\n请选择你要进行的操作:")
for menu in menuList:
print(menu)
print("——————————————————————")
option = input("请输入你要进行的操作:")
if option == "":
print(" - 您没有输入操作!")
continue
try:
if option == "1":
print(" - 显示商品信息!")
goods.show_info()
continue
elif option == "2":
print(" - 修改商品名称!")
new_goods_name = input("请输入新的商品名称:")
if goods.modify_goods_name(new_goods_name):
print(" - 修改商品名称成功!")
continue
else:
print(" - 修改商品名称失败!")
elif option == "3":
print(" - 修改进货价!")
new_purchase_price = input("请输入新的进货价:")
if goods.modify_purchase_price(float(new_purchase_price)):
print(" - 修改进货价成功!")
continue
else:
print(" - 修改进货价失败!")
elif option == "4":
print(" - 修改单价!")
new_sale_price = input("请输入新的单价:")
if goods.modify_sale_price(float(new_sale_price)):
print(" - 修改单价成功!")
continue
else:
print(" - 修改单价失败!")
elif option == "5":
print(" - 修改折扣!")
new_discount = input("请输入新的折扣:")
if goods.modify_discount(float(new_discount)):
print(" - 修改折扣成功!")
continue
else:
print(" - 修改折扣失败!")
elif option == "6":
print(" - 修改库存!")
new_stock = input("请输入新的库存:")
if goods.modify_stock(int(new_stock)):
print(" - 修改库存成功!")
continue
else:
print(" - 修改库存失败!")
elif option == "7":
print(" - 显示商品的所有信息!")
if goods.show_all_info():
print(" - 显示商品的所有信息成功!")
continue
else:
print(" - 显示商品的所有信息失败!")
elif option == "8":
print(" - 退出/切换商品!")
break
else:
print(" - 您输入的操作不存在!")
continue
# 这里对上述操作失败进行一个判断,如果是未登录则进行登录
if not goods.isLogin:
print(" - 请先登录!")
retryTimes = 3
for i in range(retryTimes):
username = input("请输入用户名:")
password = input("请输入密码:")
if goods.login(username, password):
print(" - 登录成功!")
break
else:
print(" - 登录失败!你还有", retryTimes - i - 1, "次机会!")
continue
except Exception as e:
print(f" - 操作失败!{e}")
continue
进阶
通过这个示例,我们可以学到:
- 将一个商品类拆成管理员类和商品类,便于逻辑上对题目进行拆解。
- 通过 @property 装饰器,可以将方法变成属性进行访问。
- 使用 @classmethod 装饰器,对成员变量进行递增,有记忆性,用于生成goods_id递增。
- 使用 @staticmethod 装饰器,将类中的方法单独出来作为静态方法,处理类另外的操作。
# 创建一个商品类,有:管理人员姓名、密码、商品编号、商品名称、进货单价、销售单价、销售折扣、库存共8个属性,
# 方法有:身份验证、修改商品名称、修改进货价、修改单价、修改折扣、修改库存、显示商品基础信息。
# 使用这个类创建三个对象。
# 要求:当执行:修改商品名称、修改进货价、修改单价、修改折扣、修改库存方法的时候需要身份验证。
# 显示商品显示除了进货价外的其他属性。
import random
# 管理员类
class Admin:
__username = None
__password = None
__isLogin = False
def __init__(self, username, password):
self.__username = username
self.__password = password
def verify(self, username, password):
if username == self.__username and password == self.__password:
self.__isLogin = True
return True
else:
# 一旦登录失败,就将登录状态重置为False,防止多次登录失败后,登录状态仍然为True
self.__isLogin = False
return False
# 通过 @property 装饰器,可以将方法变成属性进行访问。但限制只能读取,不能修改。
@property
def isLogin(self):
return self.__isLogin
class Goods:
__admin = None
__goods_id = 0 # 商品编号
__goods_name = None # 商品名称
__purchase_price = None # 进货单价 单位:元
__sale_price = None # 销售单价 单位:元
__discount = None # 销售折扣 0.0~1.0
__stock = None # 库存 单位:件
__errMsg = None # 收集错误信息
def __init__(self, username: str, password: str,
goods_name: str, purchase_price: float,
sale_price: float, discount: float, stock: int):
self.__goods_id = self.id_number() # 递增商品编号
self.set_goods_name(goods_name) # 商品名称
self.set_purchase_price(purchase_price) # 进货单价 单位:元
self.set_sale_price(sale_price) # 销售单价 单位:元
self.set_discount(discount) # 销售折扣 0.0~1.0
self.set_stock(stock) # 库存 单位:件
self.__errMsg = ""
# 对于Goods对象的调用者来说,不需要知道其内部的Admin对象,所以将其设置为私有属性,仅内部使用
self.__admin = Admin(username, password)
# 使用 @classmethod 装饰器,对goods_id进行递增,有记忆性
@classmethod
def id_number(cls):
cls.__goods_id = str(int(cls.__goods_id) + 1).zfill(3)
# 向前补0,补三位
return cls.__goods_id
def getIsLogin(self):
return self.__admin.isLogin
def login(self, username, password):
return self.__admin.verify(username, password)
@staticmethod
def loginByRetry(goods, retry_times=3):
"""可多次试错的登录接口,设置重试次数,默认为3次"""
if goods.getIsLogin():
# 已经登录过了,无需再次登录
return True
print(" - 请先登录!")
for i in range(retry_times):
username = input("请输入用户名:")
password = input("请输入密码:")
if goods.login(username, password):
print(" - 登录成功!")
return True
else:
print(" - 登录失败!你还有", retry_times - i - 1, "次机会!")
continue
return False
@property
def errMsg(self):
return self.__errMsg
@property
def goods_id(self):
return self.__goods_id
def get_goods_name(self):
return self.__goods_name
def set_goods_name(self, goods_name: str):
"""修改商品名称,需要管理员验证"""
if self.__goods_name and (not self.loginByRetry(self)):
# 如果属性已经被赋值,代表此操作不为初始化,是二次修改,需要验证身份
self.__errMsg = "登录失败!账号或密码错误!"
return False
# 商品名称不能为None和空
if goods_name is not None and goods_name != "":
self.__goods_name = goods_name
return True
else:
self.__errMsg = "商品名称不能为空!"
return False
def get_purchase_price(self):
return self.__purchase_price
def set_purchase_price(self, purchase_price: float):
"""修改进货价,需要管理员验证"""
if self.__purchase_price and (not self.loginByRetry(self)):
# 如果属性已经被赋值,代表此操作不为初始化,是二次修改,需要验证身份
self.__errMsg = "登录失败!账号或密码错误!"
return False
# 进货价不能为负数
if purchase_price >= 0:
self.__purchase_price = purchase_price
return True
else:
self.__errMsg = "进货价不能为负数!"
return False
def get_sale_price(self):
return self.__sale_price
def set_sale_price(self, sale_price: float):
"""修改单价,需要管理员验证"""
if self.__sale_price and (not self.loginByRetry(self)):
# 如果属性已经被赋值,代表此操作不为初始化,是二次修改,需要验证身份
self.__errMsg = "登录失败!账号或密码错误!"
return False
# 单价不能为负数
if sale_price >= 0:
self.__sale_price = sale_price
return True
else:
self.__errMsg = "单价不能为负数!"
return False
def get_discount(self):
return self.__discount
def set_discount(self, discount: float):
"""修改折扣,需要管理员验证"""
if self.__discount and (not self.loginByRetry(self)):
# 如果属性已经被赋值,代表此操作不为初始化,是二次修改,需要验证身份
self.__errMsg = "登录失败!账号或密码错误!"
return False
# 折扣范围 0.0~1.0
if 0.0 <= discount <= 1.0:
self.__discount = discount
return True
else:
self.__errMsg = "折扣不能为负数!"
return False
def get_stock(self):
return self.__stock
def set_stock(self, stock: int):
"""修改库存,需要管理员验证"""
if self.__stock and (not self.loginByRetry(self)):
# 如果属性已经被赋值,代表此操作不为初始化,是二次修改,需要验证身份
self.__errMsg = "登录失败!账号或密码错误!"
return False
# 库存不能为负数
if stock >= 0:
self.__stock = stock
return True
else:
self.__errMsg = "单价不能为负数!"
return False
def show_info(self):
"""显示商品基础信息"""
print(
f"商品编号:{self.__goods_id},商品名称:{self.__goods_name},销售单价:{self.__sale_price}元,"
f"销售折扣:{self.__discount},库存:{self.__stock}件")
def show_all_info(self):
"""显示商品所有信息,需要管理员验证"""
if not self.loginByRetry(self):
self.__errMsg = "登录失败!账号或密码错误!"
return False
print(
f"商品编号:{self.goods_id},商品名称:{self.get_goods_name()},进货单价:{self.get_purchase_price()}元,"
f"销售单价:{self.get_sale_price()}元,销售折扣:{self.get_discount()},库存:{self.get_stock()}件"
)
return True
@staticmethod
def showAllGoods(goods):
"""显示所有商品信息"""
# 格式化输出
print("{0:<10}{1:<10}{2:<10}{3:<10}{4:<10}".format("商品编号", "商品名称", "销售单价",
"销售折扣", "库存"))
for good in goods:
print(
"{0:<13}{1:<13}{2:<12}{3:<12}{4:<12}".format(good.goods_id, good.get_goods_name(),
good.get_sale_price(),
good.get_discount(), good.get_stock()))
print("————————————————————————")
if __name__ == '__main__':
goodsList = [
Goods("admin1", "123456", "苹果", 5.0, 10.0, 0.8, 100),
Goods("admin2", "123456", "香蕉", 2.0, 5.0, 0.9, 200),
Goods("admin3", "123456", "橘子", 3.0, 6.0, 0.8, 300)
]
# 商品id数组:用于判断用户输入的目标商品id是否存在于商品列表中
goodsIdList = [goods.goods_id for goods in goodsList]
# 菜单列表
menuList = [
"1.显示商品信息",
"2.修改商品名称",
"3.修改进货价",
"4.修改单价",
"5.修改折扣",
"6.修改库存",
"7.显示商品的所有信息",
"8.退出/切换商品"
]
while True:
# 打印商品信息
print("\n商品信息如下:")
Goods.showAllGoods(goodsList)
# 选择商品
goods_id = input("请输入你要操作的商品的编号(输入q则退出):")
if goods_id == "":
print(" - 您没有输入商品编号!")
continue
if goods_id == "q":
print(" - 退出程序!")
break
if goods_id not in goodsIdList:
print(" - 您输入的商品编号不存在!")
continue
# 选择商品
goodsIndex = goodsIdList.index(goods_id) # 获取商品索引
goods = goodsList[goodsIndex] # 获取商品对象
print(f" - 您选择的商品是:{goods.get_goods_name()}")
# 选择操作
while 1:
# 打印菜单
print("\n请选择你要进行的操作:")
for menu in menuList:
print(menu)
print("——————————————————————")
option = input("请输入你要进行的操作:")
if option == "":
print(" - 您没有输入操作!")
continue
try:
if option == "1":
print(" - 显示商品信息!")
goods.show_info()
continue
elif option == "2":
print(" - 修改商品名称!")
new_goods_name = input("请输入新的商品名称:")
if goods.set_goods_name(new_goods_name):
print(" - 修改商品名称成功!")
else:
print(" - 修改商品名称失败!" + goods.errMsg)
elif option == "3":
print(" - 修改进货价!")
new_purchase_price = input("请输入新的进货价:")
if goods.set_purchase_price(float(new_purchase_price)):
print(" - 修改进货价成功!")
else:
print(" - 修改进货价失败!" + goods.errMsg)
elif option == "4":
print(" - 修改单价!")
new_sale_price = input("请输入新的单价:")
if goods.set_sale_price(float(new_sale_price)):
print(" - 修改单价成功!")
else:
print(" - 修改单价失败!" + goods.errMsg)
elif option == "5":
print(" - 修改折扣!")
new_discount = input("请输入新的折扣:")
if goods.set_discount(float(new_discount)):
print(" - 修改折扣成功!")
else:
print(" - 修改折扣失败!" + goods.errMsg)
elif option == "6":
print(" - 修改库存!")
new_stock = input("请输入新的库存:")
if goods.set_stock(int(new_stock)):
print(" - 修改库存成功!")
else:
print(" - 修改库存失败!" + goods.errMsg)
elif option == "7":
print(" - 显示商品的所有信息!")
if goods.show_all_info():
print(" - 显示商品的所有信息成功!")
else:
print(" - 显示商品的所有信息失败!")
elif option == "8":
print(" - 退出/切换商品!")
break
else:
print(" - 您输入的操作不存在!")
continue
except Exception as e:
print(f" - 操作失败!{e}")
continue
高阶
本例包含三个类,分别为:商品类、管理员类、仓库类(聚合商品和管理员的类)
其中商品类和管理员类为Dao层,仓库类为控制层(Controller)
通过本例我可以学习到:
- 如何使用装饰器,以及装饰器的使用场景
- 对类的属性进行封装(私有化),以及通过@property对属性进行修改的方法
- 使用@classmethod装饰器,实现对类静态变量(goods_id)的递增操作,以及对类的实例化操作
- 使用@staticmethod装饰器,实现对类的静态方法的调用
- 使用@wraps装饰器,实现对被装饰器修饰的类的方法进行功能添加,例如登录验证,异常捕获等
- 学习定义并使用自定义装饰器:无参装饰器,有参装饰器。
- 设计模式的简单尝试。
# 作者:刘海
# 博客:https://blog.csdn.net/s1711323390/article/details/127834177
# 时间:2022年11月15日
# 题目:
# 创建一个商品类,有:管理人员姓名、密码、商品编号、商品名称、进货单价、销售单价、销售折扣、库存共8个属性,
# 方法有:身份验证、修改商品名称、修改进货价、修改单价、修改折扣、修改库存、显示商品基础信息。
# 使用这个类创建三个对象。
# 要求:当执行:修改商品名称、修改进货价、修改单价、修改折扣、修改库存方法的时候需要身份验证。
# 显示商品显示除了进货价外的其他属性。
from functools import wraps
# 本例包含五个类,分别为:商品类、管理员类、仓库类(聚合商品和管理员的类)、自定义装饰器工具类、错误信息类
# 其中商品类和管理员类为Dao层,仓库类为控制层(Controller)
# 通过本例我可以学习到:
# 1.如何使用装饰器,以及装饰器的使用场景
# 2.对类的属性进行封装(私有化),以及通过@property对属性进行修改的方法
# 3.使用@classmethod装饰器,实现对类静态变量(goods_id)的递增操作,以及对类的实例化操作
# 4.使用@staticmethod装饰器,实现对类的静态方法的调用
# 5.使用@wraps装饰器,实现对被装饰器修饰的类的方法进行功能添加,例如登录验证,异常捕获等
# 6.学习定义并使用自定义装饰器:无参装饰器,有参装饰器。
# 7.设计模式的简单尝试。
# 管理员类:该类主要用于对管理员信息的查询等操作,为Dao层
class Admin:
def __init__(self, username: str, password: str):
self.__username = username # 管理员用户名
self.__password = password # 管理员密码
self.__isLogin = False # 管理员登录状态
def verify(self, username: str, password: str):
if username == self.__username and password == self.__password:
# 登录成功,修改登录状态标记为True
self.__isLogin = True
return True
else:
# 一旦登录失败,就将登录状态重置为False,防止多次登录失败后,登录状态仍然为True
self.__isLogin = False
return False
# 通过 @property 装饰器,可以将方法变成属性进行访问。但限制只能读取,不能修改。
# 例如可以通过 admin.isLogin 来读取admin内部私有变量__isLogin的值
@property
def isLogin(self):
return self.__isLogin
# 商品类:该类主要用于对商品的基本信息进行修改,为Dao层。
class Goods:
__goods_id: str = "000" # 商品编号
def __init__(self,
goods_name: str, purchase_price: float,
sale_price: float, discount: float, stock: int):
# 这里设置goods_id时,使用self.id_number()方法,使用@classmethod装饰器。
# 这样每次创建对象时,都会自动调用该方法,在上一个创建对象的id的基础上递增id:001 002 003
self.__goods_id = self.id_number() # 递增商品编号
# 以下赋值操作,表面上是直接赋值,其实底层已经通过@xxx.setter装饰器,调用了对应的赋值方法
# 这样做的好处是,可以在赋值时,进行一些额外的操作,比如传入的参数是否合法。
self.__goods_name = goods_name # 商品名称
self.__purchase_price = purchase_price # 进货单价 单位:元
self.__sale_price = sale_price # 销售单价 单位:元
self.__discount = discount # 销售折扣 0.0~1.0
self.__stock = stock # 库存 单位:件
# 使用 @classmethod 装饰器,对goods_id进行递增,有记忆性
@classmethod
def id_number(cls):
# 向前补0,补三位,比如:001 002 003
cls.__goods_id = str(int(cls.__goods_id) + 1).zfill(3)
return cls.__goods_id
@property
def goods_id(self):
return self.__goods_id
@property
def goods_name(self):
return self.__goods_name
# 通过 @xxx.setter 装饰器,可以将赋值操作变成方法进行调用。类似于修改底层的赋值操作。
@goods_name.setter
def goods_name(self, goods_name: str):
"""修改商品名称,需要管理员验证"""
# 商品名称不能为None和空
if goods_name is None or goods_name == "":
raise ValueError(ErrorType.ParamsError("商品名称不能为空"))
self.__goods_name = goods_name
@property
def purchase_price(self):
return self.__purchase_price
@purchase_price.setter
def purchase_price(self, purchase_price: float):
"""修改进货价,需要管理员验证"""
# 进货价不能为负数
if purchase_price < 0:
raise ValueError(ErrorType.ParamsError("进货价不能为负数"))
self.__purchase_price = purchase_price
@property
def sale_price(self):
return self.__sale_price
@sale_price.setter
def sale_price(self, sale_price: float):
"""修改单价,需要管理员验证"""
# 单价不能为负数
if sale_price < 0:
raise ValueError(ErrorType.ParamsError("单价不能为负数"))
self.__sale_price = sale_price
@property
def discount(self):
return self.__discount
@discount.setter
def discount(self, discount: float):
"""修改折扣,需要管理员验证"""
# 折扣范围 0.0~1.0
if 0.0 <= discount <= 1.0:
self.__discount = discount
else:
raise ValueError(ErrorType.ParamsError("折扣范围 0.0~1.0"))
@property
def stock(self):
return self.__stock
@stock.setter
def stock(self, stock: int):
"""修改库存,需要管理员验证"""
# 库存不能为负数
if stock < 0:
raise ValueError(ErrorType.ParamsError("库存不能为负数"))
self.__stock = stock
# 错误信息类,用来规范化raise抛出的的错误信息
class ErrorType:
def __init__(self, code, msg):
self.code = code
self.msg = msg
@staticmethod
def ParamsError(errMsg):
return ErrorType(1001, "参数错误:" + errMsg)
@staticmethod
def LoginError(errMsg):
return ErrorType(1002, "登录失败:" + errMsg)
def __str__(self):
return f"错误码:{self.code}, 错误信息 - {self.msg}"
# 自定义装饰器工具类
class CustomDecoratorUtils:
# 以下两个函数为自定义装饰器,在调用被装饰器修饰的方法时,会走这两个装饰器函数。
# 用于对原本函数进行功能添加,例如在设置商品属性前,要进行登录验证,那么装饰器就用于登录验证
@staticmethod
def verify_admin(retry_times=3):
"""装饰器:调用func函数前进行管理员验证,有retry_times次重试机会"""
def outer(func):
@wraps(func)
def inner(self, *args, **kwargs):
"""可多次试错的登录接口,设置重试次数,默认为3次"""
if self.isLogin():
# 已经登录过了,无需再次登录,直接调用目标函数
return func(self, *args, **kwargs)
print(" - 请先登录!你有{}次机会.".format(retry_times))
for i in range(retry_times):
_username = input("请输入用户名:")
_password = input("请输入密码:")
if self.login(_username, _password):
print(" - 登录成功!")
# 登录成功后调用执行目标方法
return func(self, *args, **kwargs)
else:
print(" - 登录失败!你还有", retry_times - i - 1, "次机会!")
continue
raise ValueError(ErrorType.LoginError("账号或密码错误!"))
return inner
return outer
@staticmethod
def modify_catch_errors(func):
"""装饰器:该函数用于在运行func函数时若报错,则捕获异常"""
# 这里主要用于捕获当用户设置属性时,若属性值不符合要求,函数会抛出异常,被该装饰器捕获。
@wraps(func)
def wrapper(self, *args, **kwargs):
try:
func(self, *args, **kwargs)
print(" - 修改信息成功!")
except ValueError as _e:
print(" - 修改信息失败!", _e)
return wrapper
# 仓库类,该类为工厂类,属于控制层(Controller)逻辑,给用户进行逻辑层交互。
class GoodsManage:
__admin: Admin # 管理员类
__goods: Goods # 商品类
def __init__(self, admin: Admin, goods: Goods):
# 通过该 __init 方法,将管理员类和商品类传入仓库类中
self.__admin = admin
self.__goods = goods
# 也可以通过另一种构造方法实例化对象
@classmethod
def createByDetails(cls, username: str, password: str,
goods_name: str, purchase_price: float,
sale_price: float, discount: float, stock: int):
# 这种方式可以通过将零散的属性值传入,构造出一个完整的对象
admin = Admin(username, password)
goods = Goods(goods_name, purchase_price, sale_price, discount, stock)
return cls(admin, goods)
# 通过 @modify_catch_errors 这个自定义装饰器,可以在设置商品属性时,若属性值不符合要求,函数会抛出异常,被该装饰器捕获。
# 通过 @verify_admin 这个自定义装饰器,可以在设置商品属性前,要进行登录验证,那么该装饰器就用于登录验证。
# 先装饰 @modify_catch_errors 让它包裹在最外层,再装饰 @verify_admin 让它被包裹在里面,也被catch装饰器捕获。
@CustomDecoratorUtils.modify_catch_errors
@CustomDecoratorUtils.verify_admin(retry_times=2)
def modify_goods_name(self, goods_name: str):
"""修改商品名称"""
self.__goods.goods_name = goods_name
@CustomDecoratorUtils.modify_catch_errors
@CustomDecoratorUtils.verify_admin(retry_times=2)
def modify_purchase_price(self, purchase_price: float):
"""修改进货价"""
self.__goods.purchase_price = purchase_price
@CustomDecoratorUtils.modify_catch_errors
@CustomDecoratorUtils.verify_admin(retry_times=2)
def modify_sale_price(self, sale_price: float):
"""修改单价"""
self.__goods.sale_price = sale_price
@CustomDecoratorUtils.modify_catch_errors
@CustomDecoratorUtils.verify_admin(retry_times=2)
def modify_discount(self, discount: float):
"""修改折扣"""
self.__goods.discount = discount
@CustomDecoratorUtils.modify_catch_errors
@CustomDecoratorUtils.verify_admin(retry_times=2)
def modify_stock(self, stock: int):
"""修改库存"""
self.__goods.stock = stock
# 获取商品id
def get_goods_id(self):
return self.__goods.goods_id
# 获取商品名称
def get_goods_name(self):
return self.__goods.goods_name
# 获取进货价
def get_purchase_price(self):
return self.__goods.purchase_price
# 获取销售单价
def get_sale_price(self):
return self.__goods.sale_price
# 获取折扣
def get_discount(self):
return self.__goods.discount
# 获取库存
def get_stock(self):
return self.__goods.stock
# 判断是否登录
def isLogin(self):
return self.__admin.isLogin
def login(self, username: str, password: str):
return self.__admin.verify(username, password)
def show_goods_info(self):
"""显示商品基础信息或包含库存信息"""
print("商品信息如下:")
print(" - 商品编号:", self.get_goods_id())
print(" - 商品名称:", self.get_goods_name())
print(" - 单价:%.2f 元" % self.get_sale_price())
print(" - 折扣:%.2f 折" % self.get_discount())
print(" - 库存:%.2f 件" % self.get_stock())
# 不设置重试次数,那么默认为 3 次
@CustomDecoratorUtils.verify_admin(retry_times=2)
def show_all_info(self):
"""显示商品所有信息(包含库存),需要管理员验证"""
self.show_goods_info()
print(" - 进货价:%.2f元" % self.get_purchase_price())
@staticmethod
def showAllGoods(gmList: list):
"""显示所有商品的信息,gmList为GoodsManage类对象列表"""
print("商品信息如下:")
# 格式化输出
print("{0:<10}{1:<10}{2:<10}{3:<10}{4:<10}".format("商品编号", "商品名称", "销售单价",
"销售折扣", "库存"))
for goodsManageItem in gmList:
# 左对齐,保留2位小数
print(
"{0:<13}{1:<12}{2:<12.2f}{3:<12.2f}{4:<12.2f}".format(
goodsManageItem.get_goods_id(),
goodsManageItem.get_goods_name(),
goodsManageItem.get_sale_price(),
goodsManageItem.get_discount(),
goodsManageItem.get_stock())
)
print("————————————————————————")
if __name__ == '__main__':
goodsManageList = [
# 可以通过类初始化方法 __init__ 创建对象
GoodsManage(Admin("admin1", "123456"), Goods("苹果", 5.0, 10.0, 0.8, 100)),
GoodsManage(Admin("admin2", "123456"), Goods("香蕉", 2.0, 5.0, 0.9, 200)),
# 也可以通过类方法 @classmethod 创建对象
GoodsManage.createByDetails("admin3", "123456", "橘子", 3.0, 6.0, 0.8, 300),
]
# 商品id数组:用于判断用户输入的目标商品id是否存在于商品列表中
goodsIdList = [goods.get_goods_id() for goods in goodsManageList]
# 菜单列表
menuList = [
"1.显示商品信息",
"2.修改商品名称",
"3.修改进货价",
"4.修改单价",
"5.修改折扣",
"6.修改库存",
"7.显示商品的所有信息",
"8.退出/切换商品"
]
while True:
# 打印商品信息
GoodsManage.showAllGoods(goodsManageList)
# 选择商品
goods_id = input("请输入你要操作的商品的编号(输入q则退出):")
if goods_id == "":
print(" - 您没有输入商品编号!")
continue
if goods_id == "q":
print(" - 退出程序!")
break
if goods_id not in goodsIdList:
print(" - 您输入的商品编号不存在!")
continue
# 选择商品
goodsIndex = goodsIdList.index(goods_id) # 获取商品索引
goodsManageItem = goodsManageList[goodsIndex] # 获取商品对象
print(f" - 您选择的商品是:{goodsManageItem.get_goods_name()}")
# 选择操作
while 1:
# 打印菜单
print("\n请选择你要进行的操作:")
for menu in menuList:
print(menu)
print("——————————————————————")
option = input("请输入你要进行的操作:")
if option == "":
print(" - 您没有输入操作!")
continue
try:
option = int(option)
if option == 1:
print(" - 显示商品信息!")
goodsManageItem.show_goods_info()
elif option == 2:
print(" - 修改商品名称!")
new_goods_name = input("请输入新的商品名称:")
goodsManageItem.modify_goods_name(new_goods_name)
elif option == 3:
print(" - 修改进货价!")
new_purchase_price = input("请输入新的进货价:")
goodsManageItem.modify_purchase_price(float(new_purchase_price))
elif option == 4:
print(" - 修改单价!")
new_sale_price = input("请输入新的单价:")
goodsManageItem.modify_sale_price(float(new_sale_price))
elif option == 5:
print(" - 修改折扣!")
new_discount = input("请输入新的折扣:")
goodsManageItem.modify_discount(float(new_discount))
elif option == 6:
print(" - 修改库存!")
new_stock = input("请输入新的库存:")
goodsManageItem.modify_stock(int(new_stock))
elif option == 7:
print(" - 显示商品的所有信息!")
goodsManageItem.show_all_info()
elif option == 8:
print(" - 退出/切换商品!")
break
else:
print(" - 您输入的操作不存在!")
except Exception as e:
print(f" - 操作失败!请检查你输入的内容:{e}")