装饰器
装饰器

装饰器

Python装饰器

Python装饰器的作用是使函数包装与方法包装(一个函数,接收函数并返回其增强函数)变得更容易月度和理解。最初的场景是在方法定义的开头能够将其定义为类方法或静态方法。如果不使用装饰器语法的话,定义可能会非常稀疏,并且不断重复:

class WithoutDecorators:
    def some_static_method():
        print("this is static method")
    some_static_method = staticmethod(some_static_method)
    def some_class_method(cls):
        print("this is class method")
    some_class_method = classmethod(some_class_method)

闭包

def test(number):

    # 在函数内部再定义一个函数,并且这个函数用到了外边函数的变量,那么将这个函数以及用到的一些变量称之为闭包
    def test_in(number_in):
        print("in test_in 函数, number_in is %d" % number_in)
        return number+number_in
    # 其实这里返回的就是闭包的结果
    return test_in

a = test(1)
b = test(1)
print(a(2))
print(b)

修改外部函数的变量
nonlocal声明的变量不是局部变量,也不是全局变量,而是外部嵌套函数内的变量。
使用nolocal对闭包中的变量进行类似global的声明

def counter(start=0):
    def incr():

        nonlocal start
        start += 1
        return start
    return incr
a = counter(2)
print(a())

装饰器简单示例

对无参数、无返回值的函数进行装饰

来统计一个函数的运行时间

import time

def set_func(func):
    def call_func():
        start_time = time.time() # 开始的执行时间
        func()
        stop_time = time.time() # 终止的执行时间
        print("alltimes::: %f" % (stop_time - start_time))
    return call_func

@set_func
def test1():
    print("----test1----")
    for i in range(100000000):
        pass

test1()

如不加@set_func,即简单的函数调用,只会打印----test1----,
加上装饰器作用,则增加了时间统计功能:

In [43]: runfile('C:/Users/Administrator/.spyder-py3/temp.py', wdir='C:/Users/Administrator/.spyder-py3')
----test1----
alltimes::: 2.015618

对有参数、无返回值的函数进行装饰

import time

def set_func(func):
    def call_func(num): # 这里需要加参数
        start_time = time.time() 
        func(num) # 这里需要加参数
        stop_time = time.time()
        print("alltimes::: %f" % (stop_time - start_time))
    return call_func

@set_func
def test1(num): # 这里加了参数
    print("----test1----%d" % num) 
test1(1)

对有不定长参数的函数进行装饰

from time import ctime, sleep

def timefunc(func):
    def wrapped_func(*args, **kwargs):
        print("%s called at %s"%(func.__name__,ctime()))
        print(kwargs)
        func(*args, **kwargs)
    return wrapped_func

@timefunc
def foo(a, b, c,**kwargs):
    print(a+b+c)

foo(3, 5, 7,d=2,e=1)
sleep(2)
foo(2, 4, 8,d=3,e=2)

运行结果:

In [55]: runfile('C:/Users/Administrator/.spyder-py3/temp.py', wdir='C:/Users/Administrator/.spyder-py3')
foo called at Wed Feb  9 14:37:39 2022
{'d': 2, 'e': 1}
15
foo called at Wed Feb  9 14:37:41 2022
{'d': 3, 'e': 2}
14

发表回复

您的电子邮箱地址不会被公开。