小甲魚零基礎學習python_11 【變量&&閉包&&內嵌函數】

昨天的知識: 函數的變量 & 閉包 & 內嵌

昨天學完小甲魚的視頻以後偷懶沒有寫博客,今天買了美美的小裙子和巴洛克宮廷風小襯衫還是來補一下昨天的筆記和總結吧~做一個努力的美美的程序媛~


【一】 返回值:

1. python函數跟過程不同,函數一定有返回值;過程可能沒有返回值

def hello():
    print('hello world!')
temp=hello()
print(temp)
print(type(temp))
#此時沒有返回特定值,函數只返回了none對象

這裏寫圖片描述

2. python返回多個值 可以利用[ 元組 ]或者[ 列表 ]打包返回

def back():
    return(1,2,'a',45.4)
print(back())
temp=back()
print(temp[1])

這裏寫圖片描述


【二】變量:

函數變量的作用域(變量的可見性)問題: 局部變量,全局變量…

(1)

在函數內部可以訪問全局變量;

在函數外界嘗試訪問函數內部的局部變量是錯誤的,無法訪問!

def discounts(price,rate):
    final_price=price*rate
    print("old_price的值:", old_price)  #這裏訪問全局變量
    return final_price

old_price=float(input('請輸入原價:\n'))
rate=float(input('請輸入折扣率:\n'))

new_price=discounts(old_price,rate)

print('final_price的值是:', final_price)  #這裏嘗試訪問函數私有變量
print('打折後價格是:', new_price)
print('\n')

這裏寫圖片描述

(2)

在函數裏修改全局變量的操作是失敗的;因爲在函數裏的old_price會被當作和全局同名的局部變量,修改的是局部變量

def discounts(price,rate):
    final_price=price*rate
    old_price=88      #這裏試圖修改全局變量,但是其實修改的是局部變量
    print("修改後old_price的值:", old_price)
    return final_price

old_price=float(input('請輸入原價:\n'))
rate=float(input('請輸入折扣率:\n'))

new_price=discounts(old_price,rate)

print('修改後的old_price的終極值是:', old_price)  #仍然顯示輸入的值,而非88
print('打折後價格是:', new_price)

這裏寫圖片描述

這就是python採取屏蔽(shadowing)的方式來保護全局變量

|

但其實也可以在函數內部修改全局變量的值

解決方案: 可以採用global關鍵字來修改

def discounts2(price,rate):
    final_price=price*rate
    global old_price
    old_price=88     #這裏試圖修改全局變量,修改成功,因爲使用了global關鍵字
    print("修改後old_price的值:", old_price)
    return final_price

old_price=float(input('請輸入原價:\n'))
rate=float(input('請輸入折扣率:\n'))

new_price=discounts2(old_price,rate)

print('修改後的old_price的終極值是:', old_price)
print('打折後價格是:', new_price)

這裏寫圖片描述


【三】內嵌函數:

內嵌函數: 在函數內部創建另一個函數
def fuc1():
    print("fuc1正在被調用....")
    def fuc2():
        print("fuc2正在被調用....")
    fuc2()  #內嵌函數:fuc2是定義在fuc1的裏面,只能在fuc1裏調用
fuc1()
# 在外部直接調用fuc2()是錯誤的

這裏寫圖片描述


【四】閉包:

如果在一個內部函數裏,對外部作用域(但不是在全局作用域)的變量進行引用,那麼內部函數則會被認爲是閉包。

def fucx(x):
    def fucy(y):
        # fucy對外部作用域fucx(但不是在全局作用域)的變量進行引用,
        # 那麼內部函數則會被認爲是閉包
        # 所以fucy是一個閉包
        return x*y
    return fucy
i=fucx(8)
print(i)
print(type(i))

這裏寫圖片描述

可以看到這裏調用fucx只給了x的入口參數,返回的其實是的fucy,類型是一個function

正確的調用方式:

#調用方式1
print(i(5))
#調用方式2
print(fucx(8)(5))

這裏寫圖片描述

此外注意:

1. 在外部直接調用閉包函數fucy()是錯誤的!

2. 在內部函數裏只能 調用 外部函數局部變量,不能 修改 外部函數的局部變量! 如下:

 def Fuc1():
     x=5
     def fuc2():
         x*=x   #試圖修改外部函數局部變量(不是全局變量) 是錯誤的!會報錯!
         return x
     return fuc2()

解決方法1:python2 通過容器類型,比如列表元組等…

因爲容器類型不是存放在棧中,所以不會導致問題出現。
def Fuc1():
    x=[5]
    def fuc2():
        x[0]*=x[0]
        return x[0]
    return fuc2()

print(Fuc1())

解決方法2:python3 nonlocal關鍵字 ,類似於global

def Fuc1():
    x=5
    def fuc2():
        nonlocal x
        x*=x
        return x
    return fuc2()

print(Fuc1())

這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章