python 高阶知识-装饰器

一、什么是装饰器?

import time
def decorator(func):
    def wapper():
        print(time.time())
        func()
    return wapper

@decorator
def f1():
    print("This is a function named")

f1()
# anson@ansonwandeMacBook-Pro python_ToolCodes % python3 test30.py
# 1597046862.721708
# This is a function named

二、功能函数f()有入参 

1、f1(funcname) ,有1个入参

import time
def decorator(func):
    def wapper(funcname):
        print(time.time())
        func(funcname)
    return wapper

@decorator
def f1(funcname):
    print("This is a function named"+funcname)

f1("test")
# anson@ansonwandeMacBook-Pro python_ToolCodes % python3 test30.py
# 1597046983.011766
# This is a function namedtest

 

2、f1(funcname1,funcname2),有2个入参

import time
def decorator(func):
    def wapper(funcname1,funcname2):
        print(time.time())
        func(funcname1,funcname2)
    return wapper

@decorator
def f1(funcname1,funcname2):
    print("This is a function named"+funcname1)
    print("This is a function named"+funcname2)
f1("test1","test2")
# anson@ansonwandeMacBook-Pro python_ToolCodes % python3 test30.py
# 1597047095.7641442
# This is a function namedtest1
# This is a function namedtest2

 3、f1(...,...,...),有多个入参数呢?而且,decorator也不止和f1()捆绑,还会和f2(),f3()捆绑之类的,如果这些有些无参数,有些有1个,有些有2个怎么办?*args 实现

import time
def decorator(func):
    def wapper(*args):
        print(time.time())
        func(*args)
    return wapper

@decorator
def f1(funcname1,funcname2):
    print("This is a function named"+funcname1)
    print("This is a function named"+funcname2)
f1("test1","test2")
# anson@ansonwandeMacBook-Pro python_ToolCodes % python3 test30.py
# 1597047287.727742
# This is a function namedtest1
# This is a function namedtest2

 

4、特殊的关键字参数怎么兼容呢?以上装饰器是不能兼容关键字参数的,比如f3的关键字参数**kw

import time
def decorator(func):
    def wapper(*args):
        print(time.time())
        func(*args)
    return wapper

@decorator
def f1(funcname1,funcname2):
    print("This is a function named"+funcname1)
    print("This is a function named"+funcname2)
@decorator
def f2(funcname1,funcname2):
    print("This is a function named"+funcname1)
    print("This is a function named"+funcname2)
@decorator
def f3(funcname1,funcname2,**kw):
    print("This is a function named"+funcname1)
    print("This is a function named"+funcname2)
    print(kw)

f3("test1","test2",a=1,b=2,c='1,2,3')

#anson@ansonwandeMacBook-Pro python_ToolCodes % python3 test30.py
#Traceback (most recent call last):
#File "test30.py", line 22, in <module>
#f3("test1","test2",a=1,b=2,c='1,2,3')
#TypeError: wapper() got an unexpected keyword argument 'a'

怎么解决这个问题呢? 新增一个形式参数,比如用**kw(注意,形式参数是随意命名的,这里就用kw了)

import time
def decorator(func):
    def wapper(*args,**kw):
        print(time.time())
        func(*args,**kw)
    return wapper

@decorator
def f1(funcname1,funcname2):
    print("This is a function named"+funcname1)
    print("This is a function named"+funcname2)
@decorator
def f2():
    print("This is a function named")
    print("This is a function named")
@decorator
def f3(funcname1,funcname2,**kw):
    print("This is a function named"+funcname1)
    print("This is a function named"+funcname2)
    print(kw)

f3("test1","test2",a=1,b=2,c='1,2,3')
f1("test1","test2")
f2()
# anson@ansonwandeMacBook-Pro python_ToolCodes % python3 test30.py
# 1597047607.285459
# This is a function namedtest1
# This is a function namedtest2
# {'a': 1, 'b': 2, 'c': '1,2,3'}
# 1597047607.285517
# This is a function namedtest1
# This is a function namedtest2
# 1597047607.285526
# This is a function named

 三、fun()有返回值。在wrapper中保存函数计算结果,result=func(*args),然后再把返回值return 回去。

import time
def display_time(func):
    def wrapper(*args):
        t1 = time.time()
        result = func(*args)#保存
        t2 = time.time()
        print ("total time: {:.4} s".format(t2 - t1))
        return result#返回
    return wrapper

def is_prime(num):
    if num < 2:
        return False
    if num == 2:
        return True

    for i in range(2,num):
        if num%i == 0:
            return False
    return True

@display_time
def count_num_prime(maxnum):
    count = 0
    for i in range(2,maxnum):
        if is_prime(i):
            count = count + 1
    return count

count = count_num_prime(10000)
print(count)

四、装饰器的应用

1、与主功能无关的逻辑,可以全部放在装饰器中执行,让主要逻辑更加明了

2、重复执行的部分,可以抽象出来,放在装饰器中,不用写太多重复代码

 

posted @ 2020-08-10 16:25  XiaoLee-C  阅读(193)  评论(0编辑  收藏  举报