前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python装饰器详解

Python装饰器详解

作者头像
王大力测试进阶之路
发布2019-10-25 18:08:49
3790
发布2019-10-25 18:08:49
举报
文章被收录于专栏:橙子探索测试橙子探索测试

装饰器本质就是函数,作用是装饰其它函数,给其它函数增加附加功能,提高代码复用,减少代码量。

我们平时给函数增加新的功能时,通过修改此函数或在函数里调用新的函数实现,但是1、如果这个函数已经是上线的功能,这时修改程序原代码有很大风险 2、如果有100个这样的函数,我们就要找到100个地方进行修改。

例如:我们想新增功能,验证函数执行了多长时间,代码如下:

代码语言:javascript
复制
#修改原函数

import time
def sum1():
    start = time.clock()
    sum = 1+2
    print(sum)
    end = time.clock()
    print("time used:",end - start)
sum1()

"C:\Program Files\Python35\python.exe" C:/Users/wangli/PycharmProjects/Test/Test/test.py
3
time used: 2.9439962316848234e-05

Process finished with exit code 0


#原函数内调用新功能的函数
import time
def sum1():
    sum = 1+ 2
    print (sum)
def timeit(func):
    start = time.clock()
    func()
    end =time.clock()
    print("time used:", end - start)
timeit(sum1)

"C:\Program Files\Python35\python.exe" C:/Users/wangli/PycharmProjects/Test/Test/test.py
3
time used: 3.071996067845033e-05

Process finished with exit code 0


装饰器原则:

1、不能修改被装饰函数的源代码

2、不能修改被装饰函数的调用方式

实现装饰器储备知识:

高阶函数+嵌套函数=装饰器

1、函数即变量

代码语言:javascript
复制
def test1():
    print('hello!')
    return test1
test2=test1
test2()
print(test2)

"C:\Program Files\Python35\python.exe" C:/Users/wangli/PycharmProjects/Test/Test/test.py
hello!
<function test1 at 0x0000018E5D1A8F28>

Process finished with exit code 0

2、高阶函数

a:把一个函数名当做实参传给另外一个函数(在不修改被装饰函数源代码的情况下为其添加功能)

b:返回值中包含函数名

满足a或b就是高阶函数

代码语言:javascript
复制
def bar():
    print('in the bar')
def test1(func):
    print(func)
    func()
    return test1
test1(bar) #bar的内存地址+调用bar函数
print(test1)#test1的内存地址
print(test1(bar))#bar的内存地址+调用bar函数+test1的内存地址

"C:\Program Files\Python35\python.exe" C:/Users/wangli/PycharmProjects/Test/Test/test.py
<function bar at 0x0000026AC7C58F28>
in the bar

<function test1 at 0x0000026AC82C89D8>


<function bar at 0x0000026AC7C58F28>
in the bar
<function test1 at 0x0000026AC82C89D8>

Process finished with exit code 0




import time
def bar():
    time.sleep(3)
    print('in the bar')
def test1(func):
    start_time=time.time()
    func()
    stop_time=time.time()
    print('the func run time is %s'%(stop_time-start_time))
    return func
bar=test1(bar)
bar()


"C:\Program Files\Python35\python.exe" C:/Users/wangli/PycharmProjects/Test/Test/test.py
in the bar
the func run time is 3.0008511543273926
in the bar

Process finished with exit code 0

3、嵌套函数

代码语言:javascript
复制
def foo():
    print('in the foo')
    def bar():
        print('in the bar')
    bar()
foo()

"C:\Program Files\Python35\python.exe" C:/Users/wangli/PycharmProjects/Test/Test/test.py
in the foo
in the bar

Process finished with exit code 0

不带参数的装饰器:

代码语言:javascript
复制
import time
def timer(func):
    def deco():
        start_time=time.time()
        func()
        stop_time=time.time()
        print('the func run time is %s'%(stop_time-start_time))
    return deco
@timer    #test1=timer(test1)
def test1():
    time.sleep(3)
    print('in the test1')
test1()


"C:\Program Files\Python35\python.exe" C:/Users/wangli/PycharmProjects/Test/Test/test.py
in the test1
the func run time is 3.000833511352539

Process finished with exit code 0

带参数的装饰器: 从实:1中看出@timer相当于test2=timer(test2),timer(func)中func传的是test2,故func=test2 timer(test2)=deco,因为test2=timer(test2),故test2=deco=func test2(name,age)=deco(name,age)=func(name,age)所以传参到deco和func里

代码语言:javascript
复制
实例1:
import time
def timer(func):
    def deco(*args,**kwargs):
        start_time=time.time()
        func(*args,**kwargs)
        stop_time=time.time()
        print('the func run time is %s'%(stop_time-start_time))
    return deco
@timer #test1=timer(test1)
def test1():
    time.sleep(3)
    print('in the test1')
test1()
@timer  #test2=timer(test2)
def test2(name,age):
    time.sleep(3)
    print('%s %s in the test2'%(name,age))
test2('wangli',22)

"C:\Program Files\Python35\python.exe" C:/Users/wangli/PycharmProjects/Test/Test/test.py
in the test1
the func run time is 3.0001492500305176
wangli 22 in the test2
the func run time is 3.000540256500244

Process finished with exit code 0



实例2:

import time

def timmer(flag):
    """
    :param flag: 接收装饰器的参数
    :return:
    """
    def outer_wrapper(func):
        """
        :param func: 接收被装饰的函数
        :return:
        """
        # 接收被装饰函数的参数
        def wrapper(*args, **kwargs):
            """

            :param args: 收集被装饰函数的参数
            :param kwargs: 收集被装饰函数的关键字参数
            :return:
            """
            if flag == "true":
                start_time = time.time()
                # 调用被装饰的函数
                result = func(*args, **kwargs)
                # 让进程睡一秒
                time.sleep(1)
                stop_time = time.time()
                print("{func} spend {time} ".format(func="add", time=stop_time - start_time))
                return result
            else:
                print("Unexpected ending")
        return wrapper
    return outer_wrapper


本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-08-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 橙子探索测试 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档