python函数装饰器

非 Y 不嫁゛ 提交于 2019-12-14 12:00:50

1、定义:装饰器,就是把一个函数当作参数,返回一个替代版的函数
本质上就是一个返回函数的函数
2、作用:在不改变原函数的基础上给函数增加功能
3、装饰器
如:

def outer(func):  					##()中是要装饰的函数,此函数名和任意,即参数
    def inner():					##定义的要装饰的内容的函数
        print('*********')			##要装饰的内容
        func()    					##运行要装饰的函数
    return inner()  			    ##返回inner,就是返回装饰后的函数

@outer  						    ##语法糖 (在不用改变原函数的情况下,修改函数的输出结果)
def shuchu():
    print('wa ha ha')
@outer
def lizi():
    print('hello world')

例子:

def outer(func):
    def inner(age):
        if age<0:
            age = 0
        else:
            age= age
        func(age)
	return inner

	@outer
	def say(age):
	    print('name is %d years old' %(age))
	
	say(10)
	say(-10)

例子:

	def desc(fun):
def add_info():
    print('节日快乐')
    fun()
    print('下次来玩')
return add_info
@desc
def login():
    print('login...')
login()

例子,装饰器实现函数计时器

import random
		import string
		import time   				  ##导入计时器模块
		import functools   			  ##导入对装饰器装饰的模块
		li = [random.choice(string.ascii_letters)for i in range(100)]
		
		def timeit(fun):          	    ##括号中即要装饰的函数参数,可随意,但在装饰器中必须统一
		    @functools.wraps(fun)       ##对装饰器进行装饰,保留被装饰函数的函数名和帮助信息文档
		    def wapper(*args,**kwargs):     ##args是指元组,kwarges是字典,因为输入的值不一定是那种类型
		        start_time = time.time()    ##开始时间
		        res= fun(*args,**kwargs)    ##执行函数,当被装饰的函数有返回值时,需要对返回值进行接收
		        end_time = time.time()      ##结束时间
		        print('运行时间为: %.6f' %(end_time - start_time))
		        return res                      ##对接收的返回值进行返回
		    return wapper       				##返回wapper函数,即装饰后的函数
		@timeit
		def con_add():
		    s =''
		    for i in li:
		        s+=(i+',')
		    print(s)
		#con_add()
		
		@timeit
		def join_add():
		    print(','.join(li))
		#join_add()
		
		@timeit
		def fun_list(n):
		    """这是fun_list函数,被itemit装饰"""
		    return [2 * i for i in range(n)]
		
		@timeit
		def fun_map(n):
		    """这是fun_map函数,被timeit装饰"""
		    return list(map(lambda x:x*2,range(n)))
		print(fun_list.__name__)        ##显示函数名
		print(fun_list.__doc__)         ##显示函数文档
		print(fun_map.__name__)
		print(fun_map.__doc__)

例子: 创建装饰器, 要求如下:

创建add_log装饰器, 被装饰的函数打印日志信息;

日志格式为: [字符串时间] 函数名: xxx, 运行时间:xxx, 运行返回值结果:xxx

import time
import functools
#print(time.ctime())         ##显示字符串时间time.ctime()
def add_log(fun):
    @functools.wraps(fun)
    def wapper(*args, **kwargs):
        start_time = time.time()
        res = fun(*args, **kwargs)
        end_time = time.time()
        print('[%s] 函数名: %s  运行时间: %.6f 运行返回值结果: %s' % (time.ctime(), fun.__name__, end_time - start_time, res))
        return res
    return wapper

@add_log
def fun_list(n):
    return [2 * i for i in range(n)]
fun_list(5)

4、多个装饰器时候,是自上到下执行的

		def wang_a(fun):
		    def inner_a(*args,**kwargs):
		        print('A')
		        return fun(*args,**kwargs)
		    return inner_a
		
		def wang_b(fun):
		    def inner_b(*args,**kwargs):
		        print('B')
		        return fun(*args,**kwargs)
		    return inner_b
		
		
		@wang_b
		@wang_a
		def f(x):
		    print('wanghaha')
		    return x*2
		f(1)
输出结果先B 后A 

5、多个装饰器的应用场景:会采用多个装饰器先验证是否登陆成功,再验证权限是否足够
import functools
import inspect ##导入模块,可以生成一个字典
def is_admin(fun): ##判断权限
@functools.wraps(fun)
def wapper(*args,**kwargs):
inspect_res =inspect.getcallargs(fun,*args,**kwargs) ##inspect.getcallargs会返回一个字典,key值是形参value值是对应的实参

print(‘inspect的返回值是: %s’ %(inspect_res))

if inspect_res.get('name') == 'root':
    temp = fun(*args,**kwargs)
    return temp
else:
    print('not root user,no permission add student')
return wapper

login_session = ['root','admin','redhat']                       ##判断登陆
def is_login(fun):
    @functools.wraps(fun)
    def wapper(*args,**kwargs):
        if args[0] in login_session:
            temp = fun(*args,**kwargs)
            return temp
        else:
            print('Error: %s未登陆' %(args[0]))
    return wapper

@is_login
@is_admin
def add_student(name):
    print('please input student information:')

add_student('root')
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!