##python中的装饰器##

“”"
装饰器:
概念:把一个函数当作参数,返回一个替代版的函数
本质上就是一个返回函数的函数
“在不改变原函数的基础上,给函数增加功能”
“”"

def func():
    print('have a nice day!')
def func2():
    print('hello world')

def outer():
    print('**********')
    func()

#func()
outer()

“”"
其实简单的理解装饰器,就是一个化妆师,给函数化妆
“”"

def outer(func):
    def inner():
        print('****************')
        func()
    return inner #inner其实就是我们装饰后的新函数
@outer #语法糖
def func1():
    print('have a nice day!')
def func2():
    print('welcome!')
#func1= outer(func1)
func1()
#outer(func2)

“”"
outer()就相当于一个‘化妆师’
将传进来的‘参数’装饰,然后返回‘一个装饰好的函数’
“”"

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

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

def outer(func):
    # 不定长参数
    def inner(*args):
      #添加功能
        print('#################')
        func(*args)
    return inner
@outer
def say(name,age):
    print('my name is %s,I am %d years old' %(name,age))

say('tom',18)






def desc(aa): #需要传递的函数(要装饰的函数)
    def add_info():
        print('儿童节快乐~~~')
        aa()
        print('欢迎来西部开源学习~')
        
    return add_info
@desc
def login():
    print('login...')
@desc
def logout():
    print('logout...')
@desc
def savemoney():
    print('save money...')
def transfermoney():
    print('transfermoney...')
login()
logout()
savemoney()

“”"
装饰器实现一个函数计时器
“”"

import random
import string
import time
import functools
li = [random.choice(string.ascii_letters)for i in range(100)]
#print(time.time())
def timeit(fun):
    # 问题1:被装饰的函数有返回值的时候怎么办?
    # 问题2:如何保留被装饰函数的函数名和帮助信息文档
    @functools.wraps(fun)
    def wapper(*args,**kwargs):
        """这是一个wapper函数"""
        # args:元组 kwargs:字典
        # 在函数执行之前
        start_time = time.time()
        # 执行函数
        res = fun(*args,*kwargs)
        # 在函数执行之后
        end_time = time.time()
        print('运行时间为:%.6f' %(end_time - start_time))
        return res
    return wapper
@timeit
def con_add():
    s = ''
    for i in li:
        s += (i + ',')
    print(s)
@timeit
def join_add():
    print(','.join(li))
con_add()
join_add()
@timeit
def fun_list(n):
    """这是fun_list函数,被timeit装饰"""
    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(500000))
#print(fun_map(500000))
#print(fun_list.__name__)
#print(fun_list.__doc__)
#print(fun_map.__name__)
#print(fun_map.__doc__)

“”"
#创建装饰器, 要求如下:
#1. 创建add_log装饰器, 被装饰的函数打印日志信息;
#2. 日志格式为: [字符串时间] 函数名: xxx, 运行时间:xxx, 运行返回值结果:xxx
“”"

import functools
import time
#print(time.ctime())

def add_log(func):
    @functools.wraps(func)
    def wrapper(*args,**kwargs):
        start_time = time.time()
        res = func(*args,**kwargs)
        end_time = time.time()
        print('[%s] 函数名:%s,运行时间:%.6f,运行返回值结果:%d' %(
            time.ctime(),func.__name__,end_time-start_time,res
        ))
        return res
    return wrapper

@add_log
def add(x,y):
    time.sleep(1)
    return x+y

add(1,10)

“”"
[‘root’,‘admin’,‘redhat’]
多个装饰器的应用场景:
会采用多个装饰器先验证是否登陆成功,再验证权限是否足够
“”"

import functools
import inspect
def is_admin(fun):
    @functools.wraps(fun)
    def wrapper(*args,**kwargs):
        # inspect.getcallargs会返回一个字典,key值:形参 value值:对应的实参
        inspect_res = inspect.getcallargs(fun,*args,**kwargs)
        print('inspect的返回值是:%s' %(inspect_res))
        if inspect_res.get('name') == 'root':
            temp = fun(*args,**kwargs)
            return temp
        else:
            print('not root user,no permisson add student')
    return wrapper
login_session = ['root','admin','redhat']
def is_login(fun):
    @functools.wraps(fun)
    def wrapper(*args,**kwargs):
        if args[0] in login_session:
            temp = fun(*args,**kwargs)
            return temp
        else:
            print('Error:%s未登陆' %(args[0]))
    return wrapper
@is_login
@is_admin
def add_student(name):
    print('添加学生信息~')
add_student('westos')

“”
带参数的装饰器
“”

import functools
import time

def log(kind):
    def add_log(fun):
        @functools.wraps(fun)
        def wrapper(*args,**kwargs):
            start_time = time.time()
            res = fun(*args,**kwargs)
            end_time = time.time()
            print('<%s> [%s] 函数名:%s,运行时间:%.5f,运行返回值结果:%d' %
                  (kind,time.ctime(),fun.__name__,end_time-start_time,res))
            return res

        return wrapper
    return add_log

@log('aaa')
def add(x,y):
    time.sleep(1)
    return x+y

print(add(1,2))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值