python装饰器

阅读本文需要15分钟

前言

装饰器,故名失忆就是装饰用的,它可以装饰函数(其他就不知道了),装饰器用法就是在函数上一句加上
@装饰器名称
装饰器有按功能可分为函数装饰器、类装饰器,按参数分可分为带参数和不带参数,我主要用带参数的函数装饰器
装饰器的应用有:插入日志、性能测试、事务处理、缓存、权限校验。。。(感觉好高大上,我用的只是冰山一角)

栗子

假如我们要测试一个函数xxx的运行时间

def xxx(s):
	stack = []
	paren_map = {')':'(',']':'[','}':'{'}
	for c in s:
		if c not in paren_map:
			stack.append(c)
		elif not stack or paren_map[c] != stack.pop():
			return False
	return not stack

,我们首先想到在调用函数时⏲一次,调用后再⏲一次,两个时间相减

import time
if __name__ == "__main__":
    time.clock()
    xxx("{[]}{{}}[]")
    print(time.clock())
"""
这里有必要说明一下time.time()是取时间戳
而time.clock()第一次是取程序运行时间,第二次是取上次取时间到这次的间隔。(有点绕,就是第二次直接输出就是程序xxx函数运行时间了)
"""

这样写固然可以,但是以后你会厌倦这种写法,因为每次都要导入time、前面一个函数,后面加一个函数,以后删除也麻烦,而且当我们需要测试运行100次xxx的运行时间呢?在加一个for i in range(100)???,这样做的话又要修改缩进,实在太烦

但是当你使用了装饰器之后,一切都变得优雅了。

测试运行xxx所用时间
@timeit
def xxx(s):
	stack = []
	paren_map = {')':'(',']':'[','}':'{'}
	for c in s:
		if c not in paren_map:
			stack.append(c)
		elif not stack or paren_map[c] != stack.pop():
			return False
	return not stack
if __name__ == "__main__":
    xxx("{[]}{{}}[]")
测试运行100次xxx所用时间
@timeit(count=100)
def xxx(s):
	stack = []
	paren_map = {')':'(',']':'[','}':'{'}
	for c in s:
		if c not in paren_map:
			stack.append(c)
		elif not stack or paren_map[c] != stack.pop():
			return False
	return not stack
if __name__ == "__main__":
    xxx("{[]}{{}}[]")

正文

由于装饰器又涉及嵌套函数 闭包概念,为了简单起见,这些我们略过,按模板来写就好
同样是实现⏲功能

不带参数的函数装饰器

模板

def decorator(func):
    def inner(*args , **kwargs):
        ret = func(*args , **kwargs) ##这里就是相当于运行了一次下面的some_fun
        return ret+1  ##我们将结果+1后返回
    return inner
    
@decorator  ##为函数添加装饰器,这个装饰器功能就是给结果+1
def some_fun(arg1 ,,argn):
    return 1
    
ret = some_fun() ##这里的ret值就是2了

一次所用时间

def timeit(func):
    def inner(*args , **kwargs):
    	import time
    	time.clock()
        result = func(*args , **kwargs)
        return result
        print("函数运行时间:{}".format(time.clock()))
    return inner

@timeit
def xxx(s):
	stack = []
	paren_map = {')':'(',']':'[','}':'{'}
	for c in s:
		if c not in paren_map:
			stack.append(c)
		elif not stack or paren_map[c] != stack.pop():
			return False
	return not stack

if __name__ == "__main__":
    xxx("{[]}{{}}[]")

带参数的函数装饰器

模板

def decorator(arg = 0):
    def outer(func):
        def inner(*args , **kwargs):
            ret = func(*args , **kwargs)
            return ret+1
    	return inner
    return outer
@decorator(arg = 1)
def some_fun(arg1 ,,argn):
    return 1
ret = some_fun()

count次所用时间

def decorator(count=1):
    def outer(func):
        def inner(*args , **kwargs):
            import time
            time.clock()
            for i in range(count):
                result = func(*args , **kwargs)
            print("函数运行{}次时间:{}".format(count, time.clock()))
            return result
    	return inner
    return outer

@timeit(count=100)
def xxx(s):
	stack = []
	paren_map = {')':'(',']':'[','}':'{'}
	for c in s:
		if c not in paren_map:
			stack.append(c)
		elif not stack or paren_map[c] != stack.pop():
			return False
	return not stack

if __name__ == "__main__":
    xxx("{[]}{{}}[]")
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值