Python之函数进阶-闭包原理

Python之函数进阶-闭包原理

闭包

  • 自由变量:未在本地作用域中定义的变量,例如定义在内层函数外的外层函数的作用域中的变量
  • 闭包:就是一个概念,出现在嵌套函数中,指的是内层函数引用到了外层函数的自由变量,就形成了闭包。很多语言都有这个概念,最熟悉的就是JavaScript

def inc():
    c = [0]         # 自由变量
    def inner():
        c[0] += 1   # 此处+=的对象是列表中的地址引用
        return c[0]
    return inner

# 定义一个函数,inner中c[0] += 1,是否可以修改inc中c变量呢?
foo = inc()
print(1, foo())
print(2, foo())

# 执行结果是可以修改的,因为inner中修改的是列表中的引用地址。
# 返回结果:1 1
# 返回结果:2 2
c = 100
print(foo())

# 定义一个c=100的变量,然后在执行foo(),得到的结果是3,因为c变量是global全局的,print打印foo()函数,用的是函数内的变量,又执行一个所以是3.
# 返回结果:3
def a():
    x = [1]
    return id(x)

# 定义一个函数a,在函数体中定义一个变量,return 这个变量的id内存地址
a()

# 返回结果:4375700544
a()

# 每一次函数执行有关系吗?没有,是完全独立的
# 返回结果:4371940480
def inc():
    a = (100,)
    c = [0]
    print(hex(id(c)))
    def inner():
        c[0] += 1
        print(a)
        return c[0]
    return inner

foo = inc()
print(foo.__name__, type(foo.__name__))
print(foo.__closure__)
print(1, foo())
print(2, foo())

# inner中用到外层函数的自由变量被用到了,所以__closure__要记住,要不然就成垃圾了
# 返回结果:0x104cf5fc0     # 将10进制转换成16进制
# 返回结果:inner   # foo的名字是inner,类型是str
# 返回结果:(, ) # 执行closure得到的结果,在closure中记住了c的内存地址
# 返回结果:(100,) # 第一次打印内容
# 返回结果:1 1	 # 第一次打印内容
# 返回结果:(100,) # 第二次打印内容
# 返回结果:2 2	 # 第二次打印内容

图一:闭包原理

Python之函数进阶-闭包原理_第1张图片

你可能感兴趣的:(Python,python,开发语言)