练习:使用装饰器优化一等函数实现策略
我们可以实现:
商品点单
使用“策略”模式实现折扣,并利用装饰器Promo
推荐最佳折扣,利用Promo装饰器带来的好处
实现商品类
from collections import namedtuple
Order = namedtuple('Order', ['name', 'dots'])
Trr = namedtuple('Trr', ['name', 'price'])
class Cash:
"""实现结算"""
def __init__(self, order, cater, using_promo=None):
self.order = order
self.cater = cater
self.promo = using_promo
def total(self):
self.total_price = 0
for item in self.cater:
self.total_price += item.price
return self.total_price
def due(self):
return self.total_price - self.promo(self.order, self.cater, self.total_price)
def __repr__(self):
self.total()
rep = '===顾客信息===\n'
rep += '购买人名称: {}\n'.format(self.order.name)
rep += '===商品===\n'
for item in self.cater:
rep += '品名: {} 价格: {}\n'.format(item.name, item.price)
rep += '===结算===\n'
rep += '总价:{}\n'.format(self.total_price)
rep += '优惠后价格:{}'.format(self.due())
return rep
使用“策略”模式实现折扣,加入了一个全新的装饰器:promo。
# 一个用来存储打折函数的列表
promos = []
def promo(promo_func):
"""打折函数装饰器"""
promos.append(promo_func)
return promo_func
@promo # 它是一个折扣函数
def dot_promo(order, cater, total_price):
"""如果用户点数高于100,就给予8折(1-0.8)"""
if order.dots >= 100:
return total_price * 0.2
else:
return 0
@promo # 它是一个折扣函数
def half_past_promo(order, cater, total_price):
"""简单地给予一个5折"""
return total_price * 0.5
@promo # 它是一个折扣函数
def up_ten_promo(order, cater, total_price):
"""如果购物车内商品满或多于10个,则给予7.5折优惠"""
if len(cater) >= 10:
return total_price * 0.25
else:
return 0
推荐最佳折扣
def best_promo(order, cater, total):
"""找到并推荐最佳折扣,按最佳折扣计算"""
return max(found_promo(order, cater, total) for found_promo in promos) # 试验每一个优惠,使用最好的结果
开始!试验我们的代码。
# 例子一:Ben买了一个sock, 享用积分消费。
ben = Order('Ben', 1000)
ben_cash = Cash(order=ben, cater=[Trr('sock', 30), ], using_promo=dot_promo)
print(ben_cash, '\n')
# 例子二:Sally买了一个milk, 享用五折优惠。
sally = Order('Sally', 1000)
sally_cash = Cash(order=sally, cater=[Trr('milk', 25), ], using_promo=half_past_promo)
print(sally_cash, '\n')
# 例子三:我双十一买了一堆东西,享用智能优惠。
msu = Order('Su', 1000)
su_cash = Cash(order=msu, cater=[Trr('sth', 130), Trr('sth', 130), Trr('sth', 130), ], using_promo=best_promo)
print(su_cash, '\n')
# 例子四:XiaoMing双十二买了一堆东西,享用满十7.5折优惠。
ming = Order('XiaoMing', 1000)
ming_cash = Cash(order=ming, cater=[Trr('sth', 130), Trr('sth', 130), Trr('sth', 130),
Trr('sth', 130), Trr('sth', 130), Trr('sth', 130),
Trr('sth', 130), Trr('sth', 130), Trr('sth', 130), ], using_promo=dot_promo)
print(ming_cash, '\n')
输出
===顾客信息===
购买人名称: Ben
===商品===
品名: sock 价格: 30
===结算===
总价:30
优惠后价格:24.0
===顾客信息===
购买人名称: Sally
===商品===
品名: milk 价格: 25
===结算===
总价:25
优惠后价格:12.5
===顾客信息===
购买人名称: Su
===商品===
品名: sth 价格: 130
品名: sth 价格: 130
品名: sth 价格: 130
===结算===
总价:390
优惠后价格:195.0
===顾客信息===
购买人名称: XiaoMing
===商品===
品名: sth 价格: 130
品名: sth 价格: 130
品名: sth 价格: 130
品名: sth 价格: 130
品名: sth 价格: 130
品名: sth 价格: 130
品名: sth 价格: 130
品名: sth 价格: 130
品名: sth 价格: 130
===结算===
总价:1170
优惠后价格:936.0
这个程序的灵感来源于O'Reilly Media的书《流畅的Python》,作者是巴西的Luciano Ramalho。