闭包函数和装饰器

闭:指定义在函数内的函数

包:指该函数包含对外部作用域名字的引用

def f1():

    x=1

    def inner():

        print(x)

    return inner

func=f1()

def f2():

    x=1111111111    #和调用位置无关要到定义阶段去找

    func()

f2()

输出1

def f1():

    x=1

    def inner():

        print(x)

    return inner

f=f1()

f1()   # 这是一个闭包函数

 

# 为函数体传值方式 1 使用参数形式

def f1(x):

    print(x)

f1(1)

 

# 为函数体传值方式2     包给函数

def outter(x):

 

    def inner():

        print(x)

    return inner

f=outter(5)

f()

 

爬虫小例子

import  requests  # 导入模块

def outter(url):

    def get():

        response=requests.get(url)

        if response.status_code==200:

            print(response.text)

    return get

baidu=outter('https://www.baidu.com')

python=outter('https://www.python.org')

 

baidu()

baidu()

 

 

装饰器

什么是装饰器

器: 是指程序中的函数具备某种功能

装饰: 为被装饰对象添加的额外功能

装饰器可以是任意可调用的对象  被装饰的对象也可以是任意课调用的对象

 

为什么用装饰器

软件一旦上线 对修改源代码是封闭的  对扩展功能是开放的  这就用到装饰器

1 不修改被装饰对象的的源代码

不修改被装饰对象的调用方式

 

3 如何用装饰器

 

 

import  time    #  导入模块

def index():

    print('welcom to index')

    time.sleep(3)     # 推行执行时间的 秒数

index()

 

执行后没有统计多长时间   所以加个功能   统计运行时间的功能

import  time   #导入模块

def index():

    start=time.time()

    print('welcom to index')

    time.sleep(3)     # 推行执行时间的 秒数

    stop=time.time()

    print('run time is %s'%(stop-start))

index()   # 这样写改写了源代码  不可以

 

 

用装饰器写

 

import time

def index():

    print('welcom to index')

    time.sleep(3)

 

 

def timmer():

    start = time.time()

    index()

    stop=time.time()

    print('run time is %s'%(stop-start))

 

timmer()

 

但是装饰器被写死了 只能给index统计时间   以后还要用到其他的函数的统计时间

 

 

import time

def index():

    print('welcom to index')

    time.sleep(3)

 

 

def timmer(func):                    #  传入func

    start = time.time()

    func()                      #  把index变成 func()

    stop=time.time()

    print('run time is %s'%(stop-start))

 

timmer(index)             #  也不好 因为改变了调用方式

 

 

 

**************************************************************

import time

def index():

    print('welcom to index')

    time.sleep(3)

 

def timmer(func):                             #4然后外面来一个函数 把下面的缩进

  #func=index                                   #2上面写一个参数 = index

    def wrapper():    #  wrapper  是装饰的意思   #1 定义一个函数 (内部的代码块是新功能)

        start=time.time()    # 统计时间开始

        func()

        stop=time.time()    # 统计时间结束      #5在调整注释掉 2 , 把这个数放到4 的括号内

        print('run time is %s'%(stop-start))

    return wrapper                                #3 下面一个return 返回 wrapper

 

index=timmer(index)    # index是wrapper函数的地址   #6 index = timmer(index),   index()

index()

装饰器的固定写法 :

 

4然后外面来一个函数 把下面的缩进

2上面写一个参数 = index

1 定义一个函数 (内部的代码块是新功能)

3 下面一个return 返回 wrapper

5在调整注释掉 2 , 把这个数放到4 的括号内

6 index = timmer(index)

  index()

练习

 

 

import  requests

respones=requests.get('https://image.baidu.com')

respones.status_code==200

print(respones.text)

当参数传值

def func():

    print('from aaa')

def foo(v):

    print(v)

    v()

foo(func)

输出

<function func at 0x000001FBFDAFA6A8>

from aaa

 

引用

def func():

    print('from aaa')

f=func

print(f)

f()

输出

<function func at 0x0000021CC6F8A6A8>

from aaa

返回值

def func():

    print('ssssssss')

 

def foo(x):

    return x

res=foo(func)

print(res)

res()

 

输出

<function func at 0x0000014910FFA6A8>

Ssssssss

 

 

 

 

 

 

 

 

 

 

 

 

装饰器语法糖

在被装饰对象上方并且单独一行写着@ 装饰器名字

 

import time

def timmer(func):

    def wrapper(*args,**kwargs):

        start=time.time()

        res=func(*args,**kwargs)

        stop=time.time()

        print('run time is %s' %(stop-start))

        return res

    return wrapper

@timmer                  #将正下方的函数名字做参数传给timmer然后将值赋给原函数名index

def index():

    print('welcome to index')

    time.sleep(3)

    return 123

@timmer                 ##将正下方的函数名字做参数传给timmer然后将值赋给原函数名home

def home(name):

    print('welcome%sto home page'% home)

    time.sleep(2)

 

res=index()

home('egon')

#

 

总结 :  装饰器写法

 

def deco(func):

    def wrapper(*args,**kwargs):

        res=func(*args,**kwargs)

        return res

    return wrapper

posted @ 2019-06-14 18:45  andy117  阅读(128)  评论(0编辑  收藏  举报