Day16

本节内容:

1.深入了解掌握装饰器

一.装饰器

1.高阶函数满足的要求:

a.函数名可以作为参数输入

b.函数名可以作为返回值

装饰器的功能是为之前的函数添加新的功能

2.闭包(closure)是函数式编程的重要的语法结构。

定义:如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure)

def outer():
x=10
def inner():#条件一:inner就是内部函数
print(10)#条件2:外部环境是一个变量
return inner#结论:内部函数inner 就是一个闭包,返回值是一个函数名,它其实是inner的内存地址
f=outer()#返回的是inner函数的内存地址

f()#调用inner的方法,结果是10


3.装饰器函数

import time

# def showtime(f):

#     def inner():

#         start=time.time()

#         f()

#         end=time.time()

#         print(end-start)

#     return inner

# def foo():

#     print('foo...')

#     time.sleep(2)

# foo=showtime(foo)#返回的是inner函数的内存地址

# foo()#正式调用inner函数

#上面的函数等价于下面的装饰器

def showtime(f):#showtime是为函数foo添加的计算时间的新的功能#装饰器函数

    def inner():

        start=time.time()

        f()

        end=time.time()

        print(end-start)

    return inner

@showtime#等价于foo=showtime(foo)

def foo():#功能函数

    print('foo...')

    time.sleep(2)

foo()

解析装饰器函数:

 

调用foo()刚开始执行的是粉色框的代码,当使用装饰器@show_time的时候执行的是蓝色框的代码中的wrapper函数,只不过蓝色框的代码又执行了foo()函数

标记@表示装饰器函数中返回的值,函数名相当于内存地址

给功能函数加参数:

#***********************************不定长参数

import time

def show_time(func):#装饰器函数

    def wrapper(*args,**kwargs):

        start_time=time.time()

        func(*args,**kwargs)

        end_time=time.time()

        print('spend %s'%(end_time-start_time))

    return wrapper

@show_time   #add=show_time(add)

def add(*args,**kwargs):#功能函数

    time.sleep(1)

    sum=0

    for i in args:

        sum+=i

    print(sum) 

add(2,4,8,9)

 装饰器还有更大的灵活性,例如带参数的装饰器:在上面的装饰器调用中,比如@show_time,该装饰器唯一的参数就是执行业务的函数。装饰器的语法允许我们在调用时,提供其它参数,比如@decorator(a)。这样,就为装饰器的编写和使用提供了更大的灵活性。

 #下面的函数中实现的功能是实现某些功能函数执行装饰器中的功能部分,某些功能函数不执行

import time

def time_logger(flag=0):

     def show_time(func):

            def wrapper(*args,**kwargs):

                start_time=time.time()

                func(*args,**kwargs)

                end_time=time.time()

                print('spend %s'%(end_time-start_time))

                if flag:#区别下面的2个功能函数是否执行下面print代码

                    print('将这个操作的时间记录到日志中')

            return wrapper

    return show_time  

@time_logger(3)#falg值不为0它将执行print('将这个操作的时间记录到日志中')这个功能模块

def add(*args,**kwargs):

    time.sleep(1)

    sum=0

    for i in args:

        sum+=i

    print(sum)

add(2,7,5)

@time_logger(0)#falg值为0它不会执行print('将这个操作的时间记录到日志中')这个功能模块

def foo():

   print(‘foo...’)

   time.sleep(3)

foo()

Eg2: 

#实现的功能是给装饰器函数传入参数,使功能函数选择性输出打印日志的功能

# def logger(flag=''):

#     def showtime(f):#showtime是为函数foo添加的计算时间的新的功能

#         def inner():

#             start=time.time()

#             f()

#             end=time.time()

#             print(end-start)

#             if flag=='true':#是根据功能函数上面的装饰器传入的参数确定的

#                 print('日志记录')

#         return inner

#     return showtime

# @logger('true')#等价于@showtime是根据logger返回的值确定的,showtime只是记录的是内存地址

# def foo():

#     print('foo...')

#     time.sleep(2)

# foo()

# @logger()

# def bar():

#     print('bar...')

#     time.sleep(3)

# bar()

 

 






posted on 2018-08-24 10:51  summer666  阅读(164)  评论(0)    收藏  举报