装饰器
2019-07-18 本文已影响0人
四阿哥萌萌哒
闭包
# 定义一个函数
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
# 给test函数赋值,这个20就是给参数number
ret = test(20)
# 注意这里的100其实给参数number_in
print(ret(100))
#注 意这里的200其实给参数number_in
print(ret(200))
运行结果
in test_in 函数, number_in is 100 120
in test_in 函数, number_in is 200 22
闭包的作用:
1.函数名只是函数代码空间的引用,当函数名赋值给一个对象的时候 就是引用传递
2.闭包就是一个嵌套定义的函数,在外层运行时才开始内层函数的定义,然后将内部函数的引用传递函数外的对象
3.内部函数和使用的外部函数提供的变量构成的整体称为闭包
初识装饰器
def decorate(func):
def inner():
return "<i>"+func()+"</i>"
return inner
@decorate
def func():
return "你好"
print(func())
运行结果
<i>你好</i>
以看出装饰器就是在闭包的基础上做了一些修改
装饰器传参
from time import ctime, sleep
def timefun(func):
def wrapped_func(*args, **kwargs):
print("%s called at %s"%(func.__name__, ctime()))
func(*args, **kwargs)
return wrapped_func
@timefun
def foo(a, b, c):
print(a+b+c)
foo(1,2,3)
sleep(1)
foo(4,5,6)
运行结果
foo called at Thu Aug 23 21:32:50 2018
6
foo called at Thu Aug 23 21:32:51 2018
15
装饰器工厂(flask定义一个路由的方式)
from time import ctime, sleep
def timefun_arg(pre="hello"):
def timefun(func):
def wrapped_func():
print("%s called at %s %s" % (func.__name__, ctime(), pre))
return func()
return wrapped_func
return timefun
@timefun_arg("php")
def foo():
print("I am foo")
@timefun_arg("python")
def too():
print("I am too")
foo()
sleep(2)
foo()
too()
sleep(2)
too()
运行结果
foo called at Thu Aug 23 21:40:34 2018 php
I am foo
foo called at Thu Aug 23 21:40:36 2018 php
I am foo
too called at Thu Aug 23 21:40:36 2018 python
I am too
too called at Thu Aug 23 21:40:38 2018 python
I am too
小结
在面向对象(OOP)的设计模式中,decorator被称为装饰模式。OOP的装饰模式需要通过继承和组合来实现,而Python除了能支持OOP的decorator外,直接从语法层次支持decorator。Python的decorator可以用函数实现,也可以用类实现。
例如打印日志,利用装饰器可以轻松实现业务逻辑和控制逻辑的解耦
日志装饰器:
class LogPlus:
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
print 'start call {}'.format(self.func.__name__)
self.func(*args, **kwargs)
print 'end call {}'.format(self.func.__name__)
@LogPlus
def hello():
print '2017-11-06'
输出
start call hello
2017-11-06
end call hello