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("洗碗")