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

相關文章
相關標籤/搜索