在java中有个面向切面编程,在python中也有个类似的东西,那就是装饰器
使用装饰器前,先熟悉下闭包:
- 闭包是指延伸了作用域的函数,在其中能够访问未在函数定义体中定义的非全局变量。
- 未在函数定义体中定义的非全局变量一般都是在嵌套函数中出现的。
""" 闭包:在一个外函数中定义了一个内函数,内函数里运用了外函数的临时变量,并且外函数的返回值是内函数的引用,这样就构成了一个闭包。 """ def out(a): b = 5 def inner(): print(a + b) return inner if __name__ == '__main__': demo = out(5) # 内函数的引用返回给了demo # demo存了外函数的返回值,也就是inner函数的引用,这里相当于执行inner函数 demo()
python装饰器(fuctional decorators)就是用于拓展原来函数功能的一种函数,目的是在不改变原函数名(或类名)的情况下,给函数增加新的功能。
""" 装饰器: 使用函数装饰器 A() 去装饰另一个函数 B(),其底层执行了如下 2 步操作: 将 B 作为参数传给 A() 函数; 将 A() 函数执行完成的返回值反馈回 B。 """ def funA(fn): print("python") fn() print("www.python.com") return "装饰器函数的返回值" @funA def funB(): print("Java") c = funB print(c) # 装饰器函数的返回值
装饰器应用的小案例
import time def out(func): def inner(a, b): print("装饰器开始装饰...") start_time = time.time() func(a, b) end_time = time.time() s = (end_time - start_time) * 1000 print("time is %d ms" % s) return inner @out def func_1(a, b): print("--- 加法 ---") time.sleep(1) print("result is %d" % (a + b)) @out def func_2(a, b): print("--- 减法 ---") time.sleep(1) print("result is %d" % (a - b)) if __name__ == '__main__': f1 = func_1 f1(5, 2) f2 = func_2 f2(6, 3)
Python内置装饰器
在Python中有三个内置的装饰器,都是跟class相关的:staticmethod、classmethod 和property。
- staticmethod 是类静态方法,其跟成员方法的区别是没有 self 参数,并且可以在类不进行实例化的情况下调用
- classmethod 与成员方法的区别在于所接收的第一个参数不是 self (类实例的指针),而是cls(当前类的具体类型)
- property 是属性的意思,表示可以通过通过类实例直接访问的信息
示例:property的使用
""" 新式类@property的使用 """ class Goods(object): def __init__(self): # 初始化原价与折扣 self.org_price = 1000; self.discount = 0.7 # 获取价格的方法 @property def price(self): return self.org_price * self.discount # 设置价格的方法 @price.setter def price(self, data): self.org_price = data # 删除价格的方法 @price.deleter def price(self): print("执行deleter方法") goods = Goods() # goods.price ==> goods.price() print(goods.price) # goods.price ==> goods.price(600) goods.price = 600 print(goods.price) # goods.price ==> goods.price() --> @price.deleter装饰的方法 del goods.price