函数的引用与闭包

一. 引用

函数的引用是函数的内存地址,即函数在内存中的位置,一般以函数名(不加括号)表示。
举例:

# -*- coding:utf-8 -*-
def reference():
    print("function reference")
    return "this is a function reference"


print("1. 这是函数调用,需要加括号,会执行函数")
t1 = reference()
print(t1)

print("2. 这里是函数引用,无需加括号,不执行函数,传递函数名即可,它包括函数内存地址")
t2 = reference
print(t2)

print("3. 这里是函数id")
r_id = id(t2)
print(r_id)

print("4. t2为reference的引用,也可直接执行函数")
r_e = t2()
print(r_e)

print("5. 查看t2与reference的id是否相等")
r_id1 = id(t2)
r_id2 = id(reference)

结果:

1. 这是函数调用,需要加括号,会执行函数
function reference
this is a function reference
2. 这里是函数引用,无需加括号,不执行函数,传递函数名即可,它包括函数内存地址
<function reference at 0x000001C785A43E18>
3. 这里是函数id
1956452253208
4. t2为reference的引用,也可直接执行函数
function reference
this is a function reference
5. 查看t2与reference的id是否相等
r_id1: 1745876696600
r_id2: 1745876696600

二. 闭包

1. 定义

在函数的内部再定义一个内部函数,并且这个内部函数用到了外部函数的局部变量,那么将这个函数以及用到的一些变量称之为闭包。

内部函数可以叫做嵌套函数(nested function),可以理解为函数内部的局部变量。这个很好理解,因为在python中,函数可以当参数传递到另一个函数中。

2. 举例

# -*- coding:utf-8 -*-
def outer(num_out):

    def inner(num_in):
        print("在内部函数中, num_in的值为%d" % num_in)
        return num_out + num_in
    return inner


ret = outer(80)

print(ret(50))

结果:

在外部函数中, num_out的值为80
在内部函数中, num_in的值为50
130

3. 闭包理解过程

  • 程序中,代码从上往下执行,遇到函数部分先跳过,执行后续部分
  • 随后,遇到ret = outer(80)时,程序中,等式从右往左执行
  • 执行outer(80)时,执行outer函数且传入实参80给形参num_out
  • outer函数开始执行,先执行print函数,遇到inner函数同理跳过,再执行return函数
  • return innerinner为内部函数的引用,表示inner函数的内存地址,return函数inner函数内存地址返回给ret变量接收,ret表示inner函数的内存地址
  • 再往后执行print(ret(50))ret内部inner函数的引用加上括号表示函数的调用
  • 执行ret(50)时,调用inner()函数并且传入50实参给形参num_in,执行print函数,再最后执行return函数,计算num_out + num_in的和,将结果返回给ret(50)
  • 最后打印输出130

4. 闭包简单案例

求两点之间的距离

输入:

# -*- coding:utf-8 -*-
import math


def point1(a, b):
    def point2_distance(x, y):
        return math.sqrt(math.pow((a-x), 2) + math.pow((b-y), 2))
    return point2_distance


result1 = point1(2, 3)
result2 = point1(1, 1)
print(result1(5, 5))
print(result2(3, 1))

结果:

3.605551275463989
2.0

三. 嵌套函数修改外层函数变量

想要修改外部变量,需要加上nonlocal [变量名]来指明该外部变量。引用则无需指定,但是修改需要指定。

# -*- coding:utf-8 -*-
def counter(start=0):
    def increase():
        # 声明上一层函数的变量
        nonlocal start
        start += 1
        return start
    return increase


result = counter(5)
print(result())

发布了45 篇原创文章 · 获赞 1 · 访问量 2416

猜你喜欢

转载自blog.csdn.net/weixin_44225602/article/details/103663915