Python 基础之函数的嵌套与nonlocal修改局部变量及闭包函数

一.函数的嵌套

嵌套在外层,称之为外函数python

嵌套在里层,称之为内函数
#:
def outer():

    def inner():
        print("I'm inner")
    def inn2():
        print("12345")
    inn2()
    inner()
outer()

#inner()

(1)内部函数能够直接在函数外部调用吗 不能够
(2)调用外部函数后,内部函数能够在函数外部调用吗 不能够
(3)内部函数能够在函数内部调用吗  能够
(4)内部函数在函数颞部调用时,是否有前后顺序  不能够

#外部函数outer 里面是inner  ,inner里面还嵌套一个smaller 内函数,调用smaller
#:
闭包

#a = 17
def outer():
    #a = 16
    #id = 99
    def inner():
        #a = 15
        def smaller():
            #a = 10
            print(id)
            print("I'm smaller")
        smaller()
    inner()
outer()

#LEGB (就近找变量原则)函数

#寻找变量的调用顺序采用LEGB原则(即就近原则)ui

L -- Local(function): 当前函数内的做用域  (局部做用域) (局部命名空间spa

E -- Enclosing function locals:外部嵌套函数的做用域 (嵌套做用域) (局部命名空间)对象

G -- Global(module) :函数外部所在的命名空间    (全局做用域) (全局命名空间)生命周期

B -- Builtin(Python):python内置模块的命名空间 (内建做用域) (内建命名空间)

依据就近原则, 从上往下 从里向外 依次寻找

#注意点
若是先前局部变量存在a,删除以后再获取就获取不到,
若是先前不存在该局部变量,默认向上按照LEGB原则依次寻找
#:
a = 10
def func():
    a = 20
    del a
    #print(a)
func()
print(a)内存

 

二.nonlocal 修改局部变量

nonlocal 专门用于修改局部变量
(1)它自动寻找上一层空间的局部变量用来修改
(2)不停的向上寻找
(3)若是再也找不到了,直接报错
#(1) nonlocal 符合LEGB原则
def outer():
    a = 15
    def inner():
        nonlocal a
        a = 17
        print(a)
    inner()
    print(a)
outer()

#(2)nonlocal 修改的是局部变量,不是全局变量
a = 16
def outer():
    a = 10
    def inner():
        #a = 11
        def smaller():
            nonlocal a
            a +=3
            print(a)
        smaller()
    inner()
outer()

#(3) 不是用nonlocal 是否能够修改局部变量?能够
def outer():
    # a = 3
    lst = [1,2,3,4,5]
    def smaller():
        lst[2] +=5
    smaller()
    print(lst)
outer()作用域

 

 

三.闭包函数

闭包:
    内函数使用了外函数的局部变量
    而且外函数把内函数返回出来的过程是闭包
    这个内函数叫作闭包函数
#(1)  基本语法
def outer():
    a = 5
    b = 6
    #inner 是闭包函数
    def inner():
        print(a,b)
    return inner
res = outer()
print(res)
res()

#获取闭包函数使用的变量: __closure__ ,cell_contents (了解)
tup = res.__closure__
print("=====1======")
print(tup)
#获取元组里面第一个元素
obj = tup[0]
print(obj)
#使用cell_contents来获取单元对象当中的值
res = obj.cell_contents
print(res)

obj2 = tup[1]
res2 = obj2.cell_contents
print(res2)
print("<======2=======>")

#闭包的特色:
    内函数使用了外函数的局部变量,外函数的局部变量与内函数发生绑定,延长该变量的生命周期
    (实际内存给它存储了这个值,暂时不释放)
#(2)闭包函数特色
#:io

def famil():
    dejie = "one"
    erjie = "two"
    #money 局部变量由于在闭包函数中使用,因而发生绑定,延长该变量的生命周期
    money = 100000

    def dajie_hobby():
        nonlocal money
        money -=30000
        print("大姐喜欢花钱,喜欢买兰博基尼,喜欢买channel,家里钱还剩下%d" % (money))

    def erjie_hobby():
        nonlocal money
        money +=15000
        print("二姐喜欢赚钱,,家里钱赚了如今变成%d钱" % (money))

    def master():
        #返回一个元组,元组里面的每个元素是函数
        return (dajie_hobby,erjie_hobby)
    return master
func = famil()
tup = func()
print(tup)
#大姐函数
dajie = tup[0]
dajie()
#二姐函数
erjie = tup[1]
erjie()

 

输出结果为:

大姐喜欢花钱,喜欢买兰博基尼,喜欢买channel,家里钱还剩下70000

二姐喜欢赚钱,,家里钱赚了如今变成85000

相关文章
相关标签/搜索