Python闭包

之所以出现闭包就是因为在不同的作用域下出现了同名的变量
(找变量要是没找到就会向它上级去找)

# 闭包
# 函数式编程 javascript python
# 函数任意位置的定义
# 函数可以作为另外一个函数的返回值,或者参数来使用
# python 一切皆对象 函数也是对象

def a():
    def b():   # b是函数名字
        pass

    def c(b):  # b是形参
        pass
    c(b)   # b是实参
    return b

print(type(a))
# 内部函数定义在外部函数内部
def func_out():
    def func_in():
        print('i am in func_in')


    return func_in


f = func_out()
print(type(f))
f()  # 调用内部函数
# 美元转换人名币 汇率 6
# 闭包 函数+环境变量 环境参数 才可以产生闭包

def func_out():
    rate = 6
    
    def transfer(doller):
        return doller * rate

    return transfer


# rate = 7  # 7并没有改变局部变量的6,闭包现象
f = func_out()
print(f(10))

rate在局部作用域找不到会向上一层去找,要是找不到会再往外层去找,最后找到全局变量6

rate = 6  # 全局变量定义6


def func_out():
    def transfer(doller):
        return doller * rate

    return transfer


rate = 7  # 全局变量改变
f = func_out()
print(f(10))

实际应用中,为了防止混淆,作用域不同,变量名也应不同

def func1():
    x = 1
    
    def func2():
        x = 2
        print(x)  # 第二个打印的,为2

    print(x)  # 第一个打印的,为1
    func2()  # 调用func2()
    print(x)   # 第三个打印的,为1;出了func2()的,变量都为func1()的
    

func1()

在这里插入图片描述

def func1():
    x = 1

    def func2():
        y = 2
        print(y)  # 第二个打印的,为2

    print(x)  # 第一个打印的,为1
    func2()  # 调用func2()
    print(x)   # 第三个打印的,为1;出了func2()的,变量都为func1()的


func1()

作用域的知识点:在定义函数里,只要变量出现在左边并且进行赋值操作,都会被认为是局部变量

# 解释作用域的知识点
# 在定义函数里,只要变量出现在左边并且进行赋值操作,都会被认为是局部变量

x = 1


def a():
    y = 2 * x
    print(y)
    print(x)

a()

闭包有什么用

下一次结果比较依赖上一次执行结果时,比较适合闭包理论(环境参数,保存现场)

旅行者一维变量举例:

错误代码
(注释掉错误那一行也不能实现我们预期目标)

# 一维坐标 x从 0到 2 到 4

origin = 0

def gogo(step):
    target = origin + step
    origin = target   # 因为origin出现在了左边,被认为是局部变量,必须先赋值再使用
    return target

print(gogo(2))
print(gogo(3))
print(gogo(6))
不使用闭包的情况,用一个全局变量来记录每一次调用完的结果

正确代码

# 一维坐标 x从 0到 2 到 4

origin = 0

def gogo(step):
    global origin  # 用global关键字定义为全局变量
    target = origin + step
    origin = target
    return target

print(gogo(2))
print(gogo(3))
print(gogo(6))

在这里插入图片描述

使用闭包

用关键词nolocal

origin = 0

def creater(start):
    def gogo(step):
        nonlocal start  # 扩大作用域,但不是全局变量
        target = start + step
        start = target
        return target

    return gogo

f = creater(origin)
print(f(2))
print(f(3))
print(f(6))

使用闭包比较安全,第一种全局变量方法容易被修改,比如:
修改起始为100,后面也会随之变化

origin = 0

def gogo(step):
    global origin  # 用global关键字定义为全局变量
    target = origin + step
    origin = target
    return target

print("or", origin)
print(gogo(2))
print("or", origin)
print(gogo(3))
origin = 100
print("or", origin)
print(gogo(6))
print("or", origin)

在这里插入图片描述
而闭包不会
封闭包裹,将环境变量和函数的执行过程封闭在了一个私有的包里面

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值