09-Python之路—函數進階

🐴Python之路—函數進階✔️

程式設計師三大美德:

  1. 懶惰

因為一直致力於減少工作的總工作量。

  1. 缺乏耐性

因為一旦讓你去做本該電腦完成的事,你將會怒不可遏。

  1. 傲慢

因為被榮譽感沖暈頭的你會把程式寫得讓誰都挑不出毛病來。

大家好😄, 現在讓我們一起來學習一下函數進階部分的內容🎉

🍗 藥引

我們在前面學會了函數的基本使用,那麼我們來看以下的程式碼:

def myfunc(x, y):
    m = x + y

myfunc(10, 20)
print(m)

so​ 😕, 執行程式碼:

NameError: name 'm' is not defined

報錯了!程式猿🙈最怕的並不是報錯,而是報的錯誤解決不了。

我們來看下這個報錯,「name ‘m’ is not defined」,變數m沒有被定義?,但是我們明明在函數內定義了!

首先,我們看看上篇文章中的一張圖片,了解下程式碼運行時遇到函數是怎麼做的:

1. 從Python解釋器開始執行之後,就會在記憶體中開闢一個空間
2. 每當遇到一個變數時,就會把變數名和值的對應關係保存下來
   但是當遇到函數定義時,解釋器只是象徵性的把函數名讀入記憶體,表示知道有這個函數存在了,而函數內部的變數和邏輯,解釋器不關心。
3. 等調用函數時,python解釋器會在開闢一塊記憶體來存儲函數里的內容,這個時候才關注函數裡面有哪些變數,而函數中的變數只能在函數內部使用,並且會隨著函數執行完畢,這塊記憶體中的內容會被清空(垃圾回收)

這就是為什麼變數m沒有定義的原因?

而我們給這個「存放名字與值」的空間起來一個名字—命名空間

命名空間是一種絕妙的理念,讓我們盡情的使用發揮吧!—-《Python之禪》

命名空間

命名空間一共分為三種:

  • 全局命名空間—程式碼在運行伊始,創建的存儲「變數名與值的關係」的空間
  • 局部命名空間—在函數的運行中開闢的臨時的空間
  • 內置命名空間—程式運行前載入

PS:*內置命名空間中存放了python解釋器為我們提供的名字:input,print,str,list,tuple…它們都是我們拿過來就可以用的方法。

載入順序:內置命名空間–>全局命名空間–>局部命名空間

取值順序:局部命名空間–>全局命名空間–>內置命名空間

作用域

作用域就是作用範圍(銅鑼灣陳浩南😎)

按照生效範圍分為:

  • 全局作用域:包含內置名稱空間、全局名稱空間,在整個文件的任意位置都能被引用、全局有效
  • 局部作用域:局部名稱空間,只能在局部範圍內生效

global

global關鍵字的作用:全局聲明

a = 10
def func():
    global a
    a = 20

print(a)
func()
print(a)

函數嵌套

我們學過if語句嵌套,for循環嵌套,其實函數也可以嵌套

函數嵌套定義

def f1():
    print("in f1")
    def f2():
        print("in f2")

    f2()
f1()

函數嵌套調用

def max2(x, y):
    '''比較兩個數的大小'''
    m = x if x > y else y
    return m


def max4(a, b, c, d):
    res1 = max2(a, b)
    res2 = max2(res1, c)
    res3 = max2(res2, d)
    return res3


the_max = max4(23, -7, 30, 11)
print(the_max)

函數名

函數名本質上就是函數的記憶體地址

def func():
    print('in func')

print(func)		# output:<function func at 0x0000019B7FF22EA0>
  1. 可以被引用

    def func():
        print('in func')
    
    f = func
    print(f)	
    
  2. 可以被當作容器類型的元素

PS: 一句話,可以當成普通變數用

閉包

內部函數包含對外部作用域而非全劇作用域名字的引用,該內部函數稱為閉包函數

閉包的常用的用法:

def func():  # 外部函數
    name = 'mark'
    def inner():  # 內部函數
        print(name)
    print(inner.__closure__)   #判斷閉包函數的方法
    return inner

f = func()
f()

總結

命名空間

函數的嵌套

  嵌套定義:定義在內部的函數無法直接在全局被調用

函數名的本質

  就是一個變數,保存了函數所在的記憶體地址

閉包

  內部函數包含對外部作用域而非全劇作用域名字的引用,該內部函數稱為閉包函數