小白學 Python(17):基礎數據類型(函數)(下)
- 2019 年 11 月 8 日
- 筆記
人生苦短,我選Python
前文傳送門
變量作用域
變量的作用域是指在程序中命名的變量產生想過的範圍。
沒看懂?沒關係,我們寫個示例慢慢品。
a = 0 def print_1(): a = 1 print('a =', a) def print_2(): a = 2 print('a =', a) print_a()
顯示結果如下:
a = 1
在上面的示例中, a 我們進行了三次賦值,但是注意,這裡並不是賦值覆蓋,而是每次賦值時作用域不同。
第一次賦值 a 是在最外面,這個稱為全局變量,意思是它的作用域是全局的,我們在全局任何地方使用 a ,都能獲得這個值。
第二次賦值, a 是在 print_1()
這個函數中,我們調用了 print_1()
這個函數,所以這裡的賦值會生效。
第三次賦值是在 print_2()
這個函數中,我們並未調用這個函數,所以這裡 a 的賦值並不會生效。
比如我們可以這麼打印:
a = 0 def print_1(): a = 1 print('a =', a) def print_2(): a = 2 print('a =', a) print('a =', a)
打印結果如下:
a = 0
這時我們就將這個全局變量打印出來了。
第二個和第三個在方法內的 a 就成了局部變量,這兩個 a 都是只在當前的函數中生效,出了這個函數就不生效了。
如果我們將局部變量中的的賦值注釋掉,那麼在函數中是否能取到全局變量的值?
答案當然是肯定的,我們試試看:
a = 0 def print_1(): # a = 1 print('a =', a) def print_2(): a = 2 print('a =', a) print_a()
打印結果如下:
a = 0
我們還可以再做一點改變,在函數 print_1()
中調用函數 print_2()
,如下:
a = 0 def print_1(): # a = 1 print('a1 =', a) def print_2(): a = 2 print('a2 =', a) print_2() print('a3 =', a) print_1()
打印結果如下:
a3 = 0 a1 = 0 a2 = 2
此示例添加 a1 、 a2 、 a3 僅為打印後方便識別,並非這是三個變量。
注意: 內層函數的變量作用域僅在內層函數中,並不會覆蓋到外層函數。
匿名函數
是的,你沒看錯,函數是可以不命名的。
當我們需要使用匿名函數的時候,可以使用 lambda
關鍵字來聲明匿名函數。
- lambda 只是一個表達式,函數體比 def 簡單很多。
- lambda的主體是一個表達式,而不是一個代碼塊。僅僅能在lambda表達式中封裝有限的邏輯進去。
- lambda 函數擁有自己的命名空間,且不能訪問自己參數列表之外或全局命名空間里的參數。
語法:
函數對象名 = lambda 形參:表達式
我們還是寫一個簡單的匿名函數大家體會一下:
add = lambda x,y: x + y print(add(1, 2))
打印結果如下:
3
這裡是實現了我們上一篇文章中最簡單的加法,如果寫一個稍微複雜一點,比如說加上邏輯判斷的:
max_num = lambda x,y: x if x >= y else y print(max_num(5, 9))
打印結果如下:
9
建議: 當函數比較複雜的時候,不建議使用匿名函數,因為它只能是一行,寫起來不好寫的同時還不好閱讀,結構晦澀難懂,如果進行複雜的業務邏輯,匿名函數能讓寫的人懷疑人生,讀的人生不如死。真愛生命,請遠離匿名函數。
遞歸函數
一個函數是可以調用另一個函數的,如果這個函數調用自己的話,那麼這個就叫遞歸函數。
現在我們如果要求 n 的階乘:
千萬別告我你不知道什麼階乘,可能你需要回去問下你的初中數學老師。
n! = 1 * 2 * 3 * ... * n
看懂了哇,想想看代碼怎麼寫。
想不出來還是看我寫的吧:
def factorial(n): if n == 1: return 1 return n * factorial(n - 1) print('10的階乘為:', factorial(10))
打印結果:
10的階乘為: 3628800
希望各位同學一定要自己動手敲代碼。
示例代碼
本系列的所有代碼小編都會放在代碼管理倉庫 Github 和 Gitee 上,方便大家取用。