装饰器

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
上一篇下一篇

猜你喜欢

热点阅读