萬惡之源 - Python函式進階
函式引數-動態引數
之前我們說過傳參,如果我們在傳引數的時候不很清楚有哪些的時候,或者說給一個函式傳了很多引數,我們就要寫很多,很麻煩怎麼辦呢,我們可以考慮使用動態引數
形參的第三種:動態引數
動態引數分為兩種:
1.動態接受位置引數
首先我們來回顧下位置引數
1 2 3 4 |
|
現在有個問題,你們看我這體型也知道吃的不止這些,數量也沒有寫,這時我們就要用到動態引數
在引數位置用*表示接受任意引數
1 2 3 4 |
|
動態接收引數的時候要注意: 動態引數必須在位置引數後面
1 2 3 4 5 6 7 8 |
( '我想吃' ,args,a,b)
|
通過上述程式碼發現一個問題就是,我們明明給了多個引數,為什麼還會提示引數未傳遞呢?
原因就是因為這個*在搞鬼 *把所有的位置引數都給接受了,所有會報錯.我們嘗試著把a,b放在*的前面試試
1 2 3 4 5 6 |
|
動態接收引數的時候要注意:動態引數必須在位置引數後面
那預設值引數呢?
1 2 3 4 5 6 7 |
|
我們發現預設值引數寫在動態引數前面,預設值的引數是不會生效的
1 2 3 4 5 6 7 |
|
這個時候如果你不給出關鍵字傳參,那麼你的預設值是永遠都生效的
注意: 形參的順序: 位置引數 , 動態引數 , 預設引數
動態接收關鍵字引數
在python中可以動態的位置引數,但是*這種情況只能接收位置引數無法接收關鍵字引數,在python中使用**來接收動態關鍵字引數
1 2 3 4 5 6 7 |
|
動態關鍵字引數最後獲取的是一個dict字典形式
順序的問題, 在函式呼叫的時候, 如果先給出關鍵字引數, 則整個引數列表會報錯.
1 2 3 4 5 6 7 8 9 10 |
|
關鍵引數必須要放在位置引數後邊,由於實參是這個順序,所以形參接收的時候也是這個順序.也就是說位置引數必須在關鍵字引數前面.動態接收關鍵字引數也要在後面
最終順序:
位置引數 > *args(動態位置引數) > 預設值引數 > **kwargs(動態預設引數)
這四種引數可以任意的使用
如果想接收所有的引數:
1 2 3 4 |
|
動態引數還可以這樣傳參:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
字典也可以進行打散,不過需要**
1 2 3 4 5 |
|
函式的註釋:
1 2 3 4 5 6 7 8 9 10 11 |
|
名稱空間
在python直譯器開始執行之後, 就會在記憶體中開闢一個空間, 每當遇到一個變量的時候, 就把變量名和值之間的關係記錄下來, 但是當遇到函式定義的時候, 直譯器只是把函式名讀入記憶體, 表示這個函式存在了, 至於函式內部的變量和邏輯, 直譯器是不關心的. 也就是說一開始的時候函式只是載入進來, 僅此而已, 只有當函式被呼叫和訪問的時候, 直譯器才會根據函式內部宣告的變量來進行開闢變量的內部空間. 隨著函式執行完畢, 這些函式內部變量佔用的空間也會隨著函式執行完畢而被清空.
1 2 3 4 5 |
|
我們給存放名字和值的關係的空間起一個名字叫: 名稱空間. 我們的變量在儲存的時候就 是儲存在這片空間中的.
名稱空間分類:
1. 全域性名稱空間--> 我們直接在py檔案中, 函式外宣告的變量都屬於全域性名稱空間
2. 區域性名稱空間--> 在函式中宣告的變量會放在區域性名稱空間
3. 內建名稱空間--> 存放python直譯器為我們提供的名字, list, tuple, str, int這些都是內建名稱空間
載入順序:
1. 內建名稱空間
2. 全域性名稱空間
3. 區域性名稱空間(函式被執⾏行行的時候)
取值順序:
1. 區域性名稱空間
2. 全域性名稱空間
3. 內建名稱空間
1 2 3 4 5 6 |
|
作用域: 作用域就是作用範圍, 按照生效範圍來看分為 全域性作用域 和 區域性作用域
全域性作用域: 包含內建名稱空間和全域性名稱空間. 在整個檔案的任何位置都可以使用(遵循 從上到下逐⾏執行).
區域性作用域: 在函式內部可以使用.
作⽤域名稱空間:
1. 全域性作⽤用域: 全域性名稱空間 + 內建名稱空間
2. 區域性作⽤用域: 區域性名稱空間
我們可以通過globals()函式來檢視全域性作⽤用域中的內容, 也可以通過locals()來檢視區域性作 ⽤用域中的變數量和函式資訊
1 2 3 4 5 6 7 8 9 10 |
|
函式的巢狀
1. 只要遇見了()就是函式的呼叫. 如果沒有()就不是函式的呼叫
2. 函式的執行順序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
gloabal、nonlocal
首先我們寫這樣一個程式碼, 首先在全域性宣告一個變量, 然後再區域性呼叫這個變量, 並改變這 個變量的值
1 2 3 4 5 6 7 |
|
global表示. 不再使用區域性作用域中的內容了. 而改用全域性作用域中的變量
1 2 3 4 5 6 7 |
|
nonlocal 表示在區域性作用域中, 呼叫父級名稱空間中的變量.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
再看, 如果巢狀了很多層, 會是一種什麼效果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
這樣的程式如果能分析明白. 那麼作用域, global, nonlocal就沒問題了
來源:https://www.cnblogs.com/guobaoyuan/p/9779254.html