python中的abstractmethod
阅读原文时间:2023年07月09日阅读:2

# -*- coding: utf-8 -*-

from abc import ABC ,abstractclassmethod
from collections import namedtuple

Customer = namedtuple('Customer','name fidelity')

class lineItem:

  """初始化明细行:产品、数量、单价"""  
  def \_\_init\_\_(self,product,qty,price):  
      self.product = product  
      self.qty = qty  
      self.price = price

  def total(self):  
      return self.price\*self.qty

class Order:

"""客户、购物车、 促销活动"""  
def \_\_init\_\_(self, customer, cart, promotion=None):  
    self.customer = customer  
    self.cart = list(cart)  
    self.promotion = promotion

def total(self):  
    """hasattr:用法:判断是否包含对应的属性"""  
    if not hasattr(self,'\_\_total'):  
       self.\_\_total = sum(item.total() for item in self.cart)   #计算购物车里总金额  
    return self.\_\_total

def due(self):  
    if self.promotion is None:  
       discount=0  
    else:  
       discount = self.promotion.discount(self)  
    return self.total()-discount

def \_\_repr\_\_(self):  
    fmt = '<Order total:{:.2f} due :{:.2f}>'  
    return fmt.format(self.total(),self.due())

class Promotion(ABC): #策略 抽象基类

  """  
  @abstractmethod:抽象方法,含abstractmethod方法的类不能实例化,继承了含abstractmethod方法的子类必须复写所有abstractmethod装饰的方法,未被装饰的可以不重写  
  @ property:方法伪装属性,方法返回值及属性值,被装饰方法不能有参数,必须实例化后调用,类不能调用  
  @ classmethod:类方法,可以通过实例对象和类对象调用,被该函数修饰的方法第一个参数代表类本身常用cls,被修饰函数内可调用类属性,不能调用实例属性  
  @staticmethod:静态方法,可以通过实例对象和类对象调用,被装饰函数可无参数,被装饰函数内部通过类名.属性引用类属性或类方法,不能引用实例属性  
 """

  @abstractclassmethod  
  def discount(self,order):  
      """返回折扣金额、"""

class FidelityPromo(Promotion): #策略1
"""积分为1000或以上的客户提供5%的折扣"""
def discount(self,order):
return order.total()*0.05 if order.customer.fidelity>=1000 else 0

class BulkItemPromo(Promotion):#策略2
"""单个商品为20个或以上时提供10%的折扣"""

 def discount(self,order):  
     discount = 0  
     for item in order.cart:  
         if item.quantity>=20:  
            discount+=item.total()\*0.1  
     return discount

class LargeOrderPromo(Promotion):#策略3
"""订单中不同商品达到10个或以上时提供7%的折扣"""

def discount(self, order):  
    discount\_items = {item.product for item in order.cart}  
    if len(discount\_items)>=10:  
       return order.total()\*0.07  
    return 0

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章