python装饰器的使用演示

假如有一个函数,我需要给这个函数添加新功能,但是不改变这个函数的调用方式,那么就可以用到了装饰器

原始版

原函数

# _*_coding:utf8_*_
import time
def func1():
    time.sleep(1)
    print('这是函数1')
func1() 

输出结果为

C:\Python\Python36\python.exe D:/Python/Demo/装饰器.py
这是函数1

如果我需要给这个函数多添加一个打印内容,那么我就可用这样做

import time
def func1():
    time.sleep(1)
    print('这是函数1')
def func2(f):
    print('这是函数2')
    return f
func1 = func2(func1)     #创建一个新的func1 这个和前面的func1函数是不同的东西。是一个新的
func1()					 # 实现调用

输出结果为

C:\Python\Python36\python.exe D:/Python/Demo/装饰器.py
这是函数2
这是函数1

这样就实现了简单的装饰器的功能,具体实现原理就是,创建一个新的函数func2,然后把func1的名称空间当做参数传给func2,然后返回func1,没有加()也就是没有实现调用,当后面执行func1(),就实现了调用了。
没有改变func1的调用方式,但是运行func1出现的结果多了内容,这就实现了一个简单的装饰器。

python中,func1 = func2(func1)可用用@func2代替,具体优化代码如下

# _*_coding:utf8_*_
import time
def func2(f):
    print('这是函数2')
    return f
@func2
def func1():
    time.sleep(1)
    print('这是函数1')
func1()

上面是最简单的只加一个功能输出,下面这个加一个函数运行时间

# _*_coding:utf8_*_
import time
def func2(f):
    print('这是函数2')
    def inner():
        start = time.time()
        f()
        end = time.time()
        print(end-start)
    return inner
@func2
def func1():
    time.sleep(1)
    print('这是函数1')
func1()

运行结果为:

C:\Python\Python36\python.exe D:/Python/Demo/装饰器.py
这是函数2
这是函数1
1.000349521636963

加上返回值版本

上面的func1没有返回值,如果func1加上返回值,那么代码就需要改造了

# _*_coding:utf8_*_
import time
def func2(f):
    print('这是函数2')
    def inner():
        start = time.time()
        result = f()
        end = time.time()
        print(end-start)
        return result
    return inner
@func2
def func1():
    time.sleep(1)
    print('这是函数1')
    return '这是函数1的返回值'
print(func1())

结果为

C:\Python\Python36\python.exe D:/Python/Demo/装饰器.py
这是函数2
这是函数1
1.0005292892456055
这是函数1的返回值

上面实现的过程为在inner函数中,增加一个返回值,这个inner的返回结果,就是第一个func1的返回结果

加上传递参数功能

上面的代码func1没有传递参数的功能,如果需要加上参数传递呢?
代码可用这样改写

# _*_coding:utf8_*_
import time
def func2(f):
    print('这是函数2')
    def inner(a):				# 这里的a接收func1中的a的参数
        start = time.time()
        result = f(a)			 #这里的a执行
        end = time.time()
        print(end-start)
        return result
    return inner
@func2
def func1(a):
    time.sleep(1)
    print('这是函数1')
    print(a)
    return '这是函数1的返回值'
print(func1(1111111))

执行结果为:

C:\Python\Python36\python.exe D:/Python/Demo/装饰器.py
这是函数2
这是函数1
1111111
1.000321626663208
这是函数1的返回值

func1传递一个11111111,之后打印11111111

装饰器被不同的函数调用,传递不同的参数

假如func2 需要装饰func1func3,但是func1传递一个参数,func3传递二个参数,那么func2只需要把接收参数修改为*args,**kwargs即可

# _*_coding:utf8_*_
import time
def func2(f):
    print('这是函数2')
    def inner(*args,**kwargs):
        start = time.time()
        result = f(*args,**kwargs)
        end = time.time()
        print(end-start)
        return result
    return inner
@func2
def func1(a):
    time.sleep(1)
    print('这是函数1')
    print(a)
    return '这是函数1的返回值'
@func2
def func3(a,b):
    time.sleep(1)
    print('这是函数3')
    print(a)
    return '这是函数3的返回值'
发布了147 篇原创文章 · 获赞 72 · 访问量 49万+

猜你喜欢

转载自blog.csdn.net/diyiday/article/details/103480197