python中的abstractmethod

# -*- 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













猜你喜欢

转载自www.cnblogs.com/1314520xh/p/11070679.html