python3 函数引用 内部函数 闭包 nonlocal

# _*_coding=utf-8 _*_
# __author__ = 'juzi_juzi'

# python3 函数引用,内部函数,闭包,nonlocal

# 函数引用传递:直接用代码例子来说明:
def test(param1):
    print('在这里我们执行了test 函数,且参数为:{:s}'.format(param1))

# 对上面的函数进行调用
test('参数1')  # 执行结果为:在这里我们执行了test 函数,切参数为:参数1;

# 函数引用
call = test

print(id(call('参数1')))  # 8791127890048
print(id(test('参数1')))  # 8791127890048

# 上面的两行中的第一行是通过引用函数来调用函数test(),第二行是直接调用函数;
# 其实简单理解就是:函数赋值给另一个对象的时候,这就是引用传递;
# 可以理解为:只是取了个别名或者是贴上了一个新的标签;


# 闭包:内部函数和使用的外部函数提供的变量构成的整体称为闭包;
# 理解:函数内包含了函数,请内层函数使用了外部函数的参数,外层函数又调用了内层函数;
def out_func(out_parm1):
    print('进入了外层函数...且参数为:{}'.format(out_parm1))

    def in_func(in_parm1):
        result = out_parm1 * in_parm1
        print('进入了内层函数...且内层参数为:{}'.format(in_parm1))
        print('内外参数相乘的结果:{}'.format(result))
    return in_func

fun = out_func(3)
fun(2)
# out_func(3)(2)  这种写法可能更方便点;

# 这里来解释执行的过程:
# 1、fun = out_func(3) 开始真正的执行,然后跳到out_func()函数体部分:
# 2、进入out_func()并且带参数3,执行print();
#   结果为:进入了外层函数...且参数为:3;
# 3、def in_func(in_parm1): 这里只是定义函数,并没有真正的去执行,所以跳过这个函数的函数体部分;
# 4、return in_func 执行这个步骤,将返回的in_func(函数)赋给fun;
# 其实这个时候,fun=in_func(),这么就可以理解为fun 这个引用指向了in_func()这个函数;
# 此时就变成简单的函数引用了;
# 5、fun(2) 就相当于in_func(2)了,所以直接执行内部的in_func函数,参数为2;
# 6、 result = out_parm1 * in_parm1,那么进行计算,in_parm1 参数是外部函数的3,out_parm1
# 就是fun(2) 中携带的2,所以计算的结果应该是6;
# 7、打印内层参数,#进入了内层函数...且内层参数为:2
# 8、再打印计算的结果#内外参数相乘的结果:6
# 所以这里执行的结果为:内外参数相乘的结果:6

# 总结:
#     闭包其实就是函数内再套个函数,外层函数开始运行的时候,内层只是定义,
#     然后外层返回内层函数的调用;
#     提高代码复用率,但是由于闭包引用了外部函数的参数,所以外部的参数没有及时释放,会消耗内存;

#nonlocal: 使用该关键字来修改外层函数变量的值;

#**************************************************************************
#***********************  nonlocal 修改外部变量  **************************
#**************************************************************************
n = 10  #n  在这里定义为全局变量;
def out_():
    n = 1 # 局部变量n;
    def in_():
        nonlocal n  # nolocal 是python3 中增加进来的,在闭包中(内部函数)可直接访问
        # 外层的变量,但是不能对外部的变量进行修改,添加了nolocal 关键字可修改上层作用域
        # 的变量,如果不是用此关键字,上层的变量只能访问不能修改;
        print(n)
        n = 100
        print(n)
    print(n)
    return in_
out_()()
print(n) #这里的n 是全局变量,如果在声明初始化后没有修改(global)此变量,则此值仍与初始化时保持一致;
原文地址:https://www.cnblogs.com/juzib/p/12084910.html