from abc import ABCMeta, abstractmethod # 装饰器引入 class Person(metaclass=ABCMeta): '''人''' def __init__(self, name): self._name = name @abstractmethod def wear(self): print("着装:") class Engineer(Person): def __init__(self, name, skill): super().__init__(name) self.__skill = skill def wear(self): print(f"我是 {self.__skill}工程师 {self._name}", end=", ") super().wear() class Teacher(Person): def __init__(self, name, title): super().__init__(name) self.___title = title def getTitle(self): return self.__title def wear(self): print(f"我是 {self._name}{self.getTitle()}", end=", ") super().wear() class ClothingDecorator(Person): '''服装装饰器的基类''' def __init__(self, person): self._decorated = person def wear(self): self._decorated.wear() self.decorate() @abstractmethod def decorate(self): pass class CasualPantDecorator(ClothingDecorator): def __init__(self, person): super().__init__(person) def decorate(self): print("一条橙色的休闲裤") class BeltDecorator(ClothingDecorator): def __init__(self, person): super().__init__(person) def decorate(self): print("一条银色针扣头的皮带") class LeatherShoesDecorator(ClothingDecorator): def __init__(self, person): super().__init__(person) def decorate(self): print("一条深色休闲皮鞋") def testDecorator(): # tony = Engineer("Tony", "后端") # pant = CasualPantDecorator(tony) # belt = BeltDecorator(pant) # shoes = LeatherShoesDecorator(belt) shoes = LeatherShoesDecorator(BeltDecorator(CasualPantDecorator(Engineer("Tony", "后端")))) shoes.wear() # 1、装饰器:函数装饰函数装饰函数 def log(func): def inner(*args, **kwargs): print(f"start call {func.__name__}") res = func(*args, **kwargs) print(f"end call {func.__name__}") return res return inner @log def hello(num): for i in range(num): print(f"Hello {i}") # hello = log(hello) # hello == log.inner True # hello(20) # 2、装饰器:函数装饰类,实现单例模式 def singleton(cls): # 必须是可变变量,否则 instances = [] def inner(*args, **kwargs): if not instances: instances.append(cls(*args, **kwargs)) return instances[0] return instances[0] return inner @singleton class Foo: def __init__(self, name): self._name = name def show(self): print(self._name) # Foo = singleton(Foo) # f1 = Foo("Foo1") # f2 = Foo("Foo2") # f1.show(), f2.show() # 3、类装饰类:必须实现call方法 class Singleton: def __init__(self, cls): self._class = cls self._instance = None def __call__(self, *args, **kwargs): if self._instance: return self._instance else: self._instance = self._class(*args, **kwargs) return self._instance @Singleton class Bar: def __init__(self, name): self._name = name def show(self): print(self._name) # Bar = Singleton(Bar) # bar = Bar("bar1") # bar.show() # 4、带参数的装饰器:日志装饰器:只被调用指定次 def log(times): # 必须是可变类型,否则当下面在改变其值的时候,地址就会发生变化,显示未定义错误 temps = [] temps.append(times) def outer(func): def inner(*args, **kwargs): if temps[0] > 0: print(f"start call {func.__name__}") temps[0] = temps[0] - 1 res = func(*args, **kwargs) print(f"end call {func.__name__}") else: res = func(*args, **kwargs) return res return inner return outer @log(20) def do(string): print(f"我正在{string}") for i in range(30): do("洗碗")