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