闭包函数

Python-13

一、闭包函数

1. 什么是闭包函数

  • 闭包函数,是定义在一个函数体里面的函数,这个函数有对外部作用域中名字的引用(外层范围:包含对外部作用域而非全局作用域的引用,外部作用域名字不能出最外层的函数)

2. 闭包函数的基本使用

def outter(x):  # 也可以使用参数代替,更加灵活,相当于x=1,下面x=1就可以省略了
    # x=1       # 必须要有x=1才叫闭包函数,这个x可以是传进来的参数
    def inner():
        print(x)
    return inner

f=outter(1)
f()
  • 要求:使用函数,获取网站网页的信息
  • 闭包函数相对于普通函数,可以更方便的调用
  • 需要先安装requests模块

Alt text

# 方法一:
import requests
# 在全局空间里没有url变量值,需要每次调用自己输入
def get(url):
    respinse=requests.get(url)
    if respinse.status_code == 200:
        print(respinse.text)

baidu=get('https://www.baidu.com') # 这种情况每次调用都要赋值
# 方法二:不用每次调用都输入值
import requests

def outter(url):
    # 相当于url='https://www.bai.com',不用每次调用都赋值
    def get():
        respinse=requests.get(url)
        if respinse.status_code == 200:
            print(respinse.text)
    return get

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

二、装饰器(闭包函数的应用)

1. 什么是装饰器

  • 装饰器:可以为其他函数添加额外的功能,装饰器就是函数(暂时理解为函数)
  • 装饰器本身可以是任意可调用的对象,即,被装饰的对象也可以是任意可调用的对象

2. 装饰器必须遵循的两大原则

  • 不修改被装饰对象的源代码
  • 不修改被装饰对象的调用方式
  • 背景原因:软件的维护应该遵循开放封闭原则,即,软件一旦上线运行后,对修改源代码是封闭的,但是对扩展功能是开放的

3. 无参装饰器

import time
def index():
    print('welcome to index')
    time.sleep(3)
要求:添加显示代码运行多长时间的功能,使用装饰器来完成
方法一:
def wrapper():
    start=time.time()
    index()
    stop=time.time()
    print('run time is %s' %(stop-start))
问题:虽然功能实现了,但是改变了调用方式
方法二:
def timmer():
    func=index
    def warpper():
        start=time.time()
        func()
        stop=time.time()
        print('run time is %s' % (stop - start))
    return warpper

f=timmer() # 相当于f=warpper
问题:这种形式func=index被固定住了,不能更换其他参数,因此需要将func当做传参使用
方法三:
def timmer(func):
    # 就相当于func=index
    def warrpper():
        start=time.time()
        func()
        stop=time.time()
        print('run time is %s' %(stop-start))
    return warrpper # 打破层级限制就需要函数对象
f=timmer(index)   # 参数为被装饰函数的内存地址
f()
问题:目的是让用户使用方式和以前一样,即,以index()的形式调用函数,需要将最后改为如下形式
index=timmer(index)   # index不同命名空间的名字不冲突
index()
  • 说明:time.time() 表示当前时间

4. 装饰器修正

① 返回值修正

如果被装饰的函数,有返回值需求

Alt text

import time
def index():
    print('welcome to index')
    time.sleep(3)
    return 123

def timmer(func):
    def wrapper():
        start=time.time()
        res=func()
        stop=time.time()
        print('run time is %s' % (stop - start))
        return res
    return wrapper

index=timmer(index)
res=index()
print(res)
② 参数修正
  • 被修饰函数,有传入参数的需求,要求可以接收任意形式的参数
import time
def index():
    print('welcome to index')
    time.sleep(3)
    return 123

def home(name):
    print('My name is %s' %name)

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

index=timmer(index)
home=timmer(home)
home('xdw')

Alt text

③ 装饰器语法糖

语法格式:

装饰器放上面
@(Python)装饰器名字(说明:单独一行)
被装饰函数

@装饰器名字的作用:

  • 把正下方的函数名作为参数,传给自己,相当于装饰器名字(正下方函数名)(说明:单独一行)
  • 然后,将返回值,赋值给原函数名,代替了:index=timmer(index)
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  # @装饰器名称
# 被装饰器函数
def index():
    print('welcome to index')
    time.sleep(3)
    return 123
 
@timmer   # 多个函数需要装饰,就需要写多个,@装饰器
def home(name):
    print('My name is %s' %name)

# 调用 
index()
home('egon')

4. 装饰器的基本形式

def deco(func):
    def wrapper(*args,**kwargs):
        res=func(*args,**kwargs) # func为被装饰对象
        return res
    return wrapper

转载于:https://www.cnblogs.com/itone/p/9524555.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值