09-Python之路---函式進階

不喜歡馬賽克的馬克發表於2020-05-22

?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()

總結

名稱空間

函式的巢狀

  巢狀定義:定義在內部的函式無法直接在全域性被呼叫

函式名的本質

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

閉包

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

相關文章