python里的装饰器

2018-1-29

1.首先我们要知道什么是函数?
函数是将一段代码逻辑,通过特殊的语法组织起来,它可以有参数和返回值,也可以在别的地方被调用!

def res(int x,int y):
    sum=x+y;
    return sum;

print(res(2,3)); 

def是关键字,res是函数名,x与y是参数,
sum=x+y是函数体,return sum是返回语句。

函数可以有参数,也可以没有,可以有返回值,也可以没有,
python中返回值默认返回None。

2.什么是装饰器?
先写一个简单的装饰器,看不懂没事的

def log(func):
    def wrapper(*args,**kwargs): #动态参数
        print("begin call %s"%func.__name__)
        temp=func(*args,**kwargs) #动态参数
        print("after call %s"%func.__name__)
    return temp
return wrapper

装饰器本质上就是一个函数,
用来装饰别的函数,给其他函数附加新的功能。

原则:
(1)不能修改被装饰的函数的源代码
(2)不能修改被装饰函数的调用方式

应用场景:插入日志,性能测试,处理事务。

有一个功能,测试一个函数的运行时间

import time
def f():
    print("i am f")
    time.sleep(2)

def new_f():
    s_time=time.time() #开始时间
    f()
    e_time=time.time() #结束时间
    print("耗时:%s"%(e_time-s_time))

new_f() #调用该函数

为什么我们需要装饰器呢?

如果我们一个项目中的每个函数都需要计算运行时间呢?难道我们要将计算时间的代码复制到每一个函数中去?而且我们的调用方式可能也发生了变化!因为f()变了,那么我们的new_f()也可能也变了!这未免也太重复了。。。

我们还需要理解下面的概念:
(1)函数即变量

def f():
    print("i am f")
    time.sleep(2)

n=f
n() #就可以执行这个函数

函数就是一个变量,那么它就可以作为参数,也可以作为返回值。

(2)高阶函数
以函数作为参数,或者以函数作为返回值的函数

(3)函数嵌套
函数里面定义函数

高阶函数 + 嵌套函数 <- 装饰器

我们来写一个装饰器来实现之前的那一个功能

def my_time(func):
    s_time=time.time()
    func()
    e_time=time.time()
    print("%s耗时%s"%(func.__name__,(e_time-s_time)))

貌似区别不是很大。。。

def my_time(func):
    def wrapper():
        s_time=time.time()
        func()
        e_time=time.time()
        print("%s耗时%s"%(func.__name__,(e_time-s_time)))
    return wrapper

n=my_time() #n => wrapper
f=n
n=my_time() #n => wrapper
f=n

可以转换为:

@my_time #这就是一个装饰器
def f():
    print("i am f")
    time.sleep(2)

如果一个函数需要加两个功能?
那么我们就多重装饰器,但是我们对顺序做出了要求。
相当于一层一层的,从里到外依次装饰,从外到里依次运行。

(1)加上返回值:

@my_time
def f():
    return "i am f"

此时我们用装饰器就会出错,因为装饰器里面没有返回值,所以我们需要将装饰器带上返回值

def my_time(func):
    def wrapper():
        temp=func()
    return temp
return wrapper

(2)加上参数:

@my_time
def f(int x,int y):
    return x+y

此时我们用装饰器就会出错,因为装饰器里面没有参数,所以我们需要将装饰器带上参数

def my_time(func):
    def wrapper(a,b):
        temp=func(a,b)
    return temp
return wrapper

如果说我们的参数个数不一定的话,那么我们就需要使用动态参数了。

但是我们还需要更加高级的装饰器。。。

我们需要装饰器内print的是变量

def log(text):
    def decortator(func):
        def wrapper(*args,**kwargs):
            print(text)
            temp=func(*args,**kwargs)
        return temp
    return wrapper
return decortator

@log('xueyi')
def f(x,y):
    return x+y

好神奇啊!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值