python闭包函数


内容概要

  • 名称空间作用域
  • global与nonlocal关键字使用
  • 函数对象(函数名)
  • 函数的嵌套调用
  • 函数的嵌套定义
  • 闭包函数
  • 装饰器概念

内容详细

一、名称空间作用域

作用域
	名称空间所能够作用的范围

内置名称空间
	程序任何阶段任何位置均可使用(全局有效)
全局名称空间
	程序任何阶段任何位置均可使用(全局有效)
局部名称空间
	一般情况下只在各自局部名称空间中有效

二、global与nonlocal关键字的使用

'''
如果想在局部修改全局数据
	如果数据为不可变类型则需要关键字global声明
	如果数据为可变类型则不需要global声明
'''
# 无global
x = 10
def index():
    x = 20
index()
print(x)  # 10
# 添加global
x = 10
def index():
    global x
    x = 20
index()
print(x)  # 20

y = [11, 22]
def func():
    y.append(333)

print(y)  # [11, 22]

'''
如果想要在内部的局部修改外部局部的不可变类型
需要关键字nonlocal声明
'''
def index():
    x = 111
    def func():
        x = 222
    func()
    print(x)
index()  # 111

def index():
    x = 111
    def func():
        nonlocal x
        x = 222
    func()
    print(x)
index()  # 222

三、函数对象

# 1、函数可以被当作变量值赋值
def func():
    pass
res = func
res()  # 本质就是在调用func()函数

# 2、函数可以成为函数的实参
def func1():
    pass
def index(fun):
    pass
index(func1)

# 3、函数可以被当作返回值返回
def outer():
    def wrapper(*args, **kwargs):
        pass
    return wrapper
res = outer()
print(res)  # 函数wrapper的内存地址
'''
函数不加括号被当作返回值,是返回一个函数的内存地址
'''
# 4、函数可以是列表、元组等容器类型的元素
def index():
    pass
res = [11, 33, index]
print(res)  # [11, 33, ]

四、函数的嵌套调用

# 嵌套调用:函数内部调用其他函数
def index():
    print('函数index')
def func():
    index()
    print('函数func')
func()

五、函数的嵌套定义

# 函数体内部定义其他函数
# 将复杂的功能全部隐藏起来,暴露一个简单的接口
def all_func(type):
    def register():
        print('注册功能')
    def login():
        print('登录功能')
    def transfer():
        print('转账功能')
    def shopping():
        print('购物功能')
    # 这里仅仅是延时嵌套定义的现象 暂不考虑优化
    if type == '1':
        register()
    elif type == '2':
        login()
    elif type == '3':
        transfer()
    elif type == '4':
        shopping()
    else:
        print('不知道啥功能')

all_func('3')

六、闭包函数

闭:定义在函数中的函数
包:内层函数能调用外层函数局部名称空间的变量名

'''闭包函数:其实是给函数传参的第二种方式'''
# 方式1:函数体代码需要用到数据 直接在括号内定义形参即可
def index(username):
    print(username)
def my_max(a, b):
    if a > b:
        return a
    return b
# 方式2:利用闭包函数
def outer(x,y):
    # x = 2
    # y = 40
    def my_max():
        if x > y:
            return x
        return y
    return my_max
res = outer(2,40)
print(res())
print(res())


def outer(x, y):
    def wrapper(*args, **kwargs):
        print(x)
        print(y)
    return wrapper
res = outer(2, 3)
res()
# 爬虫测试
import requests

url = input('输入要爬取的网址:')

def outer(url):
    def spider():
        res = requests.get(url)
        if res.status_code == 200:
            with open(r'spider.html', 'wb') as f:
                f.write(res.content)
    return spider

start = outer(url)
start()

七、装饰器概念

'''装饰器是由 名称空间、函数对象、闭包函数的知识点组合而来的'''

器:工具
装饰:给被装饰对象添加额外的功能

装饰期的原则
	开放封闭原则
    	开放:对扩展开放
        封闭:对修改封闭

装饰器核心思想:
	在不改变"被装饰对象的原代码"和"原有调用方式"的前提下,给被装饰对象添加新功能
    
import time


def index():
    time.sleep(3)
    print('from index')

start_time = time.time()
index()
end_time = time.time()
# time.time(): 时间戳,统计1970年1月1日所过的秒数
use_time = end_time - start_time
print(use_time)  # 3.003939390182495