1. 程式人生 > >Python 全棧開發四 python基礎 函數

Python 全棧開發四 python基礎 函數

函數名 包裝 bsp 函數返回 數據 傳參 條件 給定 *args

一、函數的基本語法和特性

函數的定義

函數一詞來源於數學,但編程中的「函數」概念,與數學中的函數是有很大不同的。函數是指將一組語句的集合通過一個名字(函數名)封裝起來,要想執行這個函數,只需調用其函數名即可。

python中函數的分類

  1. 內置函數
  2. 自定義函數

特性:

  1. 減少重復代碼
  2. 使程序有更好的擴展性
  3. 讓程序更容易維護

定義一個函數

你可以定義一個由自己想要功能的函數,以下是簡單的規則:

  • 函數代碼塊以 def 關鍵詞開頭,後接函數標識符名稱和圓括號()
  • 任何傳入參數和自變量必須放在圓括號中間。圓括號之間可以用於定義參數。
  • 函數的第一行語句可以選擇性地使用文檔字符串—用於存放函數說明。
  • 函數內容以冒號起始,並且縮進。
  • return [表達式] 結束函數,選擇性地返回一個值給調用方。不帶表達式的return相當於返回 None。

函數的語法

 1 #函數
 2 def fun1(a,b):      #a,b 是指形參       
 3     ‘‘‘fun1‘‘‘
 4     print(in the fun1)
 5     return 0
 6 
 7 #註意函數是有返回值的
 8 #過程
 9 def fun2():
10     ‘‘‘fun2‘‘‘
11     print(in the fun2)
12 #沒有返回值的函數我們一般讓我是函數的過程
13 #函數式編程就是這種模式

二、函數的參數

參數:

首先說明,在python中,函數定義好後是存放在內存裏面的,類似我們通常所說的變量。而形參沒有任何實際意義,只有在被調用的時候才會分配內存單元,而函數調用結束後則會被釋放;而實參可以是常量,變量、表達式、函數等,實參被調用時必須得有確定的值,這樣才可以把這些值傳給形參。

技術分享圖片

參數的分類:形參,默認參數,不定長參數,關鍵字參數

默認參數:即有些情況下,一些參數必須提供,默認的情況下是一個固定的值,只有在少數情況下會修改,這種情況可以選擇默認參數。

不定長參數:在定義函數時,不確定用戶需要傳入多少個參數,這時使用不定長參數。

關鍵字參數:一般情況下,傳入參數必須按照給定的參數順序傳入,若不一定知道參數的順序,可以使用關鍵字參數來傳入。

註意:在傳入參數的時候位置參數必須在關鍵字參數的前面。

 1 ##參數形式
 2 #1不傳參
 3 def fun1():
 4      print(不能傳參數)
 5 
 6 
 7 #2必備參數
 8 def fun2(a):
 9      print(必須傳參數:,a)
10 
11 
12 #3默認參數
13 def fun3(b=2):
14      print(默認參數:,b)  #可傳可不傳
15 #可選參數
16 def fun4(*arg):  
17      print(可傳0個到多個:,arg)#可傳0個到多個 包裝成元組
18 #fun4(*[1,2])    加個* ,就把裏面的殼去掉(解包)
19 
20 
21 
22 #關鍵字參數
23 #定義的時候是跟必備參數一樣的
24 #必須放到最後
25 
26 def fun6(**kwarg):
27      print(關鍵字參數,kwarg)# 可傳0個到多個 包裝成字典
28 #fun6(a=1,b=2)  遵循變量命名規則
29 #fun6(**{‘a‘:1})   必須是字符串
30 
31 
32 ##參數混合的時候   關鍵字參數放最後 根據定義的順序 確保必備參數只能拿到值,並且只能一個
33 #必備參數+默認參數
34 def fun7(a,b=1):   #默認參數必須在必備參數的後面
35      print(a,b)
36      
37 def fun8(b,m=1,*a):
38      print(b)
39      print(m)
40      print(a)
41 
42 def fun8(*a,b,m):  #盡量不用這種方式,這種方式需要用關鍵字的方式傳入參數
43      print(a,b,m)
44      print(b)
45 
46 def fun9(*a,b,m=1):
47      print(a,b,m)
48      print(b)

一般情況下按照以下形式傳入參數:這樣更容易理解程序。

 1 def fun1(x,y=2):
 2     print(x)
 3     print(y)
 4 
 5 # fun1(1)      #默認參數,在調用函數的時候可以不傳參
 6 # fun1(1,3)     #也可以選擇傳參
 7 
 8 def fun2(*args):   #不定長參數,當不確定參數的長度時用不定長參數
 9     print(args)
10 
11 # fun2(1,3,4,5,‘d‘)
12 
13 def fun3(**kwargs):#關鍵字參數,接受N個關鍵字參數,並把它們轉換為字典
14     print(kwargs)
15 
16 fun3(i = lll)
17 
18 def fun4(a,b = 1,*args,**kwargs):
19     print(a)
20     print(b)
21     print(args)
22     print(kwargs)
23 fun4(1,2,3,3,3,x = lll)   #傳參的時候關鍵字參數必須在位置參數後面

變量:

在函數中,變量分為全局變量和局部變量。

在子程序中定義的變量稱為局部變量,在程序的一開始定義的變量稱為全局變量。

全局變量作用域是整個程序,局部變量作用域是定義該變量的子程序。

當全局變量與局部變量同名時:

在定義局部變量的子程序內,局部變量起作用;在其它地方全局變量起作用。

 1 school = oleboy  #全局變量
 2 
 3 def charge_school():
 4     school = TANZHOU   #在函數裏面是一個局部變量
 5     print(school)
 6 # charge_school()
 7 # print(school)
 8 #上面可以看出,在調用函數後,函數外部並沒有改變school的值
 9 
10 def charge_school2():
11     global school
12     school = TANZHOU
13     print(school)
14 charge_school2()
15 print(school)
16 #重上面看出,當申明global之後,函數內的變量成為了全局變量,在函數
17 #內也可以進行訪問並修改,在日常工作中做好不要這麽做
18 
19 
20 names = [Alex,Jack,Wallace]
21 name_tuple= (1,2,3,4)
22 
23 def charge_name():
24     names[1]=金角大王
25     print(names)
26 charge_name()
27 print(names)
28 
29 ‘‘‘從上可看出,當函數內的變量和全局變量為可變對象時,在函數內可以對其進行修改
30 ‘‘‘
31 a = 1   #全局變量
32 
33 def fun():
34     global a
35     a = 2   #局部變量,正常情況下無法修改全局變量,若要修改用global  最好不要這麽做
36     print(a)
37 
38 print(a)
39 b = fun()
40 print(a)

雖然在實例上,通過global可以將一個局部變量聲明為全局變量,但是這種方式對於代碼的可維護上非常不好,盡量避免這種操作。

三、返回值

函數的返回值可以是大多數的數據類型,也可以是變量名,函數名也可以是函數本身:

1 def text1():
2     print(in the text1)
3     return 0,{0,1},[0,1,3]
4 
5 def text2():
6     return text1  返回的是函數
7 
8 y = text2()()  #可以進行調用

四、嵌套函數

嵌套函數指的是,函數內定義另一個函數例:

1 def fun1():
2     print("fun1")
3     def fun2():
4        print("fun2")
5     fun2()
6 >>a = fun1()
7 fun1  #先調用fun1,在fun1裏面調用fun2
8 fun2

嵌套函數的具體用法將會在後面的學習中提到。

五、遞歸

遞歸函數是指函數內部調用自己,這樣的函數就是遞歸函數。

1 def fun1(n):
2     if n == 1:
3         return 1      #遞歸的結束條件
4     else:
5         return fun1(n-1)+1
6 >>print(fun1(3))
7 3

遞歸的必備條件:

  1. 必須有一個明確的結束條件
  2. 每次進入更深層遞歸時,問題的規模相比上次遞歸都應有所減少

遞歸的局限性:

遞歸的效率不高,遞歸層次過多會導致棧溢出(在計算機中,函數調用是通過棧(stack)這種數據結構實現的,每當進入一次函數調用,棧就會加一層棧幀,每當函數返回,棧就會減一層棧幀。有用棧的大小不是無限的,所以遞歸掉用的次數過多,就會導致棧溢出)

遞歸的應用,二分法查找:

 1 data = [1, 3, 6, 7, 9, 12, 14, 16, 17, 18, 20, 21, 22, 23, 30, 32, 33, 35]
 2 
 3 def binary_search(dataset,find_num):
 4     print(dataset)
 5 
 6     if len(dataset) >1:
 7         mid = int(len(dataset)/2)
 8         if dataset[mid] == find_num:  #find it
 9             print("找到數字",dataset[mid])
10         elif dataset[mid] > find_num :# 找的數在mid左面
11             print("\033[31;1m找的數在mid[%s]左面\033[0m" % dataset[mid])
12             return binary_search(dataset[0:mid], find_num)   #再次調用原函數
13         else:# 找的數在mid右面
14             print("\033[32;1m找的數在mid[%s]右面\033[0m" % dataset[mid])
15             return binary_search(dataset[mid+1:],find_num)
16     else:
17         if dataset[0] == find_num:  #find it
18             print("找到數字啦",dataset[0])
19         else:
20             print("沒的分了,要找的數字[%s]不在列表裏" % find_num)
21 
22 >>binary_search(data,66)
23 [1, 3, 6, 7, 9, 12, 14, 16, 17, 18, 20, 21, 22, 23, 30, 32, 33, 35]
24 找的數在mid[18]右面
25 [20, 21, 22, 23, 30, 32, 33, 35]
26 找的數在mid[30]右面
27 [32, 33, 35]
28 找的數在mid[33]右面
29 [35]
30 沒的分了,要找的數字[66]不在列表裏

六、匿名函數

匿名函數沒有函數名,一般情況就是只調用一次,後續不會再調用。

1 cala = lambda n:n*n  #一般用於只調用一次
2 ‘‘‘
3 相當於
4 def fun1(n):
5     return n*n
6 ‘‘‘
7 print(cala(10))

七、高階函數

高階函數指的是將函數名作為參數傳入。

1 def high_fun(a,b,f):
2     return f(a)+f(b)
3 
4 >>a = high_fun(1,-2,abs)  #abs()求一個函數的絕對值
5 3

上面例子中,參數f可以任意的函數名。

八、內置函數

技術分享圖片

註:內置函數將會作為另一章進行詳細的講解。

Python 全棧開發四 python基礎 函數