iT邦幫忙

2024 iThome 鐵人賽

DAY 12
2
自我挑戰組

每日挑戰:從零開始的 Python 學習之旅系列 第 12

【Day 12】基礎語法 - 函數基礎篇 - 續集

  • 分享至 

  • xImage
  •  

Hi 大家好,

今天要開始介紹基礎語法中的函數基礎篇之續集,那我們開始吧!

早一點回傳(Early Return)

Q: 什麼是早一點回傳?
A: 把注意力放在實際要做的事情上,而不是流程判斷上。

[情境一]

 在[情境一]中,print("Hello a, b")這一行是永遠不會被執行,因為只要遇到return這個關鍵字,不是只會把結果回傳,還會立刻結束這個函數的執行。

def add(a, b):
    return a + b
    print("Hello a, b")

print(add(1, 2))
PS D:\Project\practice> python hi.py
3
PS D:\Project\practice>

[情境二]

def find_even_number(numbers):
    for number in numbers:
        if number % 2 == 0:
            return number  # 早一點回傳,找到第一個偶數後立即回傳
    return None  # 如果沒有偶數,則回傳None

print(find_even_number([1, 3, 5, 7, 8, 10]))  # 輸出8
PS D:\Project\practice> python hi.py
8
PS D:\Project\practice> 

函數是一等公民 (First-Class Citizen)

Q: 什麼是一等公民?
A: 在Python中把函數和其它資料型態的值(例如:數字、字串、串列等等)看成是等價的,因為可以當作變數的值或是當作其它函數的參數來傳遞。

 在範例中會把add函數當成變數的值,賦值給變數value,在print中的value加上()去表示去執行函數,顯示結果。也可以把add函數當作值放入到串列中。

def add(a, b):
    return a + b

value = add
print(value(2, 4))

data_list = [123, "hello", add]
print(data_list)
print(data_list[-1](1, 2))
PS D:\Project\5xcampus\Python\practice> python hi.py
6
[123, 'hello', <function add at 0x0000022949628A40>]
3
PS D:\Project\5xcampus\Python\practice>

作用域(scope)

在其它程式語言中,會分成兩種,一種是全域(Global),另外一種是區域(Local),而在Python中可以區分成四種作用域範圍,分別是:
區域(Local, L)封閉(Enclosing, E)全域(Global, G)內建(Built-in, B)

LEGB規則

  • 會先找Local的區域範圍 => Local (內層函數內的範圍)
  • 找不到會往上層的範圍去找 => Enclosing (外層函數到內層函數之間的範圍)
  • 最後都找不到才會找到最外層 => Global (外層函數以外的範圍)
  • 以上三個層級都找不到才會去找Python內建函數

[情境一]

a = 1 # 這裡是指定

def hi():
    print(a) <=== 因為在hi()的範圍內沒有a,所以會往外找

hi() # 印出 1 (會印出外面的a)

[情境二]

a = 1 # 這裡是指定

def hi():
    a = 9
    print(a) <=== 在hi()範圍內有找到a,所以會印出範圍內的a

hi() # 印出 9

[情境三]

a = 1 # 這裡是指定

def hi():
    # 第一個"a"是表示宣告一個a變數,在建立期的時候會變成TDZ
    # 接下來a要先+1才會賦值給第一個"a"變數,所以在a尚未賦值之前就先進行+1的動作,
    # 這時候就會發生錯誤
    a = a + 1
    print(a)

hi()

[情境四] 使用global關鍵字

a = 1 # 這裡是指定

def hi():
    # 從現在開始你指定的a是外面的a,a就變成全域變數,就不是宣告 
    global a  <==== a = 1
    a = 2     <==== 這裡的a會被指定為2
    print(a)

hi() # 2
print(a) # 2

[情境五] 使用global關鍵字

a = 1 # 這裡是指定

def hi():
    # 從現在開始你指定的a是外面的a,a就變成全域變數,就不是宣告 
    global a  <==== a = 1
    a = 2     <==== 這裡的a會被指定為2
    print(a)

hi() # 2
print(a) # 2

[情境六] 使用nonlocal關鍵字

a = 0

def hi():
    a = 1 #Enclosing 就算底下有多層def 最多還是只會找到Enclosing 不會找到global
    # Enclosing 作用範圍在hi() ~ hey()之間
    def hey():
        # global a 的話會找到最外面的a = 0
        # nonlocal a 的話會找到local外面的a,也就是Enclosing
        nonlocal a # <=== 這裡的 a 會去找到hi()底下的 a = 1
        a = 5 # a = 5 會取代 hi()底下的 a
        print(a) # 5

    hey()
    print(a) # 5 因為原本的a = 1被取代掉成為 a = 5,所以這裡會印出 5

hi() # <=== 執行 hi() 
print(a) # 0 <=== 這裡印出的是最外層全域變數 a

image

[情境七] 那內建keyword來當作變數的影響

a = 0
print = 789  # <=== 使用內建print當作變數指定789

def hi():
    # Enclosing 作用範圍
    a = 1 #Enclosing 就算底下有多層def 最多還是只會找到Enclosing 不會找到global
    print = 456 # <=== 使用內建print當作變數指定456

    def hey():
        nonlocal a

        print = 123 # <=== 使用內建print當作變數指定123
        a = 2
        print(a)

    hey()
    print(a)

print(a) # <===== 發生錯誤

image

那今天就介紹到這裡,我們明天見~


上一篇
【Day 11】基礎語法 - 函數基礎篇
下一篇
【Day 13】基礎語法 - 函數進階篇
系列文
每日挑戰:從零開始的 Python 學習之旅30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言