1. 程式人生 > >python基礎篇11-函數

python基礎篇11-函數

port ren nat 調用函數 _for chinese 虛擬 來源 被調用

函數  

函數一詞來源於數學,但編程中的「函數」概念,與數學中的函數是有很大不同的,具體區別,我們後面會講,編程中的函數在英文中也有很多不同的叫法。在BASIC中叫做subroutine(子過程或子程序),在Pascal中叫做procedure(過程)和function,在C中只有function,在Java裏面叫做method。函數能提高應用的模塊性,和代碼的重復利用率。你已經知道Python提供了許多內建函數,比如print()。但你也可以自己創建函數,這被叫做用戶自定義函數。

定義: 函數是指將一組語句的集合通過一個名字(函數名)封裝起來,要想執行這個函數,只需調用其函數名即可

特性:

1.代碼重用

2.保持一致性

3.可擴展性

函數的創建

1.格式

Python 定義函數使用 def 關鍵字,一般格式如下:

1 #def 函數名(參數列表):
2 #    函數體
3 
4 def hello():
5     print(hello)
6    
7 hello()#調用

2.函數的命名規則

  1. 函數名必須以下劃線或字母開頭,可以包含任意字母、數字或下劃線的組合。不能使用任何的標點符號;
  2. 函數名是區分大小寫的。
  3. 函數名不能是保留字。

3.形參和實參

形參:形式參數,不是實際存在,是虛擬變量。在定義函數和函數體的時候使用形參,目的是在函數調用時接收實參(實參個數,類型應與實參一一對應)

實參:實際參數,調用函數時傳給函數的參數,可以是常量,變量,表達式,函數,傳給形參

區別:形參是虛擬的,不占用內存空間,.形參變量只有在被調用時才分配內存單元,實參是一個變量,占用內存空間,數據傳送單向,實參傳給形參,不能形參傳給實參。

1 import time
2 times=time.strftime(%Y--%m--%d)
3 def f(time):
4     print(Now  time is : %s%times)
5 f(times)

4.實例

現在我們就用一個例子來說明函數的三個特性:

技術分享圖片
 1 def action1(n):
 2     print
(starting action1...) 3 4 with open(日誌記錄,a) as f: 5 f.write(end action%s\n%n) 6 7 def action2(n): 8 print (starting action2...) 9 10 with open(日誌記錄,a) as f: 11 f.write(end action%s\n%n) 12 13 def action3(n): 14 print (starting action3...) 15 16 with open(日誌記錄,a) as f: 17 f.write(end action%s\n%n) 18 19 action1(1) 20 action2(2) 21 action3(3) 22 23 24 ##***************代碼重用 25 26 def logger(n): 27 with open(日誌記錄,a) as f: 28 f.write(end action%s\n%n) 29 30 def action1(): 31 print (starting action1...) 32 logger(1) 33 34 35 def action2(): 36 print (starting action2...) 37 logger(2) 38 39 40 def action3(): 41 print (starting action3...) 42 logger(3) 43 44 45 action1() 46 action2() 47 action3() 48 49 ##***************可擴展和保持一致 50 ##為日誌加上時間 51 import time 52 53 def logger(n): 54 time_format=%Y-%m-%d %X 55 time_current=time.strftime(time_format) 56 57 with open(日誌記錄,a) as f: 58 f.write(%s end action%s\n%(time_current,n)) 59 60 def action1(): 61 print (starting action1...) 62 logger(1) 63 64 65 def action2(): 66 print (starting action2...) 67 logger(2) 68 69 70 def action3(): 71 print (starting action3...) 72 logger(3) 73 74 action1() 75 action2() 76 action3()
函數的特性展示

函數的參數

  • 必備參數
  • 關鍵字參數
  • 默認參數
  • 不定長參數

1.必須參數

必需參數須以正確的順序傳入函數。調用時的數量必須和聲明時的一樣。

1 def f(name,age):
2  
3     print(I am %s,I am %d%(name,age))
4  
5 f(alex,18)
6 f(alvin,16)

2.關鍵字參數

關鍵字參數和函數調用關系緊密,函數調用使用關鍵字參數來確定傳入的參數值。使用關鍵字參數允許函數調用時參數的順序與聲明時不一致,因為 Python 解釋器能夠用參數名匹配參數值。

1 def f(name,age):
2  
3     print(I am %s,I am %d%(name,age))
4  
5 # f(16,‘alvin‘) #報錯
6 f(age=16,name=alvin)

3.默認參數

調用函數時,缺省參數的值如果沒有傳入,則被認為是默認值。下例如果sex沒有被傳入,會打印默認的sex:

1 def print_info(name,age,sex=male):
2  
3     print(Name:%s%name)
4     print(age:%s%age)
5     print(Sex:%s%sex)
6     return
7  
8 print_info(alex,18)
9 print_info(鐵錘,40,female)

4.不定長參數

你可能需要一個函數能處理比當初聲明時更多的參數。這些參數叫做不定長參數,和上述2種參數不同,聲明時不會命名。

1 def add(*args):
2     sum=0
3     for v in args:
4         sum+=v
5    #print(args)    輸出(1,4,6,9),即會以元組的形式存放參數 
6     return sum
7  
8 print(add(1,4,6,9))
9 print(add(1,4,6,9,5))

  加了星號(*)的變量名會存放所有未命名的變量參數。而加(**)的變量名會存放命名的變量參數:

1 def print_info(**kwargs):
2     print(kwargs)  #輸出:{‘sex‘: ‘female‘, ‘name‘: ‘alex‘, ‘ability‘: ‘Python‘, ‘age‘: 18, ‘nationality‘: ‘Chinese‘, ‘hobby‘: ‘girl‘}即以字典的方式存放變量
3     for i in kwargs:
4         print(%s:%s % (i, kwargs[i]))  # 根據參數可以打印任意相關信息了
5 
6     return
7 
8 
9 print_info(name=alex, age=18, sex=female, hobby=girl, nationality=Chinese, ability=Python)

位置:

 1 def print_info(name,*args,**kwargs):#def print_info(name,**kwargs,*args):報錯
 2  
 3     print(Name:%s%name)
 4  
 5     print(args:,args)
 6     print(kwargs:,kwargs)
 7  
 8     return
 9  
10 print_info(alex,18,hobby=girl,nationality=Chinese,ability=Python)
11 # print_info(hobby=‘girl‘,‘alex‘,18,nationality=‘Chinese‘,ability=‘Python‘)  #報錯
12 #print_info(‘alex‘,hobby=‘girl‘,18,nationality=‘Chinese‘,ability=‘Python‘)   #報

註意,還可以這樣傳參:

1 ef f(*args):
2     print(args)
3  
4 f(*[1,2,5])
5  
6 def f(**kargs):
7     print(kargs)
8  
9 f(**{name:alex})

函數的返回值

要想獲取函數的執行結果,就可以用return語句把結果返回。

註意:

  • 函數在執行過程中只要遇到return語句,就會停止執行並返回結果,所以也可以理解為 return 語句代表著函數的結束;
  • 如果未在函數中指定return,那這個函數的返回值為None;
  • return多個對象,解釋器會把這多個對象組裝成一個元組作為一個一個整體結果輸出。

作用域

1.作用域介紹:

python中的作用域分4種情況:

  • L:local,局部作用域,即函數中定義的變量;
  • E:enclosing,嵌套的父級函數的局部作用域,即包含此函數的上級函數的局部作用域,但不是全局的;
  • G:globa,全局變量,就是模塊級別定義的變量;
  • B:built-in,系統固定模塊裏面的變量,比如int, bytearray等。 搜索變量的優先級順序依次是:作用域局部>外層作用域>當前模塊中的全局>python內置作用域,也就是LEGB。
 1 x = int(2.9)  # int built-in
 2  
 3 g_count = 0  # global
 4 def outer():
 5     o_count = 1  # enclosing
 6     def inner():
 7         i_count = 2  # local
 8         print(o_count)  #輸出1
 9    #print(i_count) 找不到
10     inner()  
11 outer()
12  
13 # print(o_count) #找不到

2.作用域的產生:

在Python中,只有模塊(module),類(class)以及函數(def、lambda)才會引入新的作用域,其它的代碼塊(如if、try、for等)是不會引入新的作用域的,如下代碼:

1 if 2>1:
2     x = 1
3 print(x)  # 1

這個是沒有問題的,if並沒有引入一個新的作用域,x仍處在當前作用域中,後面代碼可以使用。

1 def test():
2     x = 2
3 print(x) # NameError: name ‘x2‘ is not defined

def、class、lambda是可以引入新作用域的。print(x)中的x不處於當前作用域中。

3.變量的修改:

 1 #################
 2 x=6
 3 def f2():
 4     print(x)
 5     x=5
 6 f2()
 7   
 8 # 錯誤的原因在於print(x)時,解釋器會在局部作用域找,會找到x=5(函數已經加載到內存),但x使用在聲明前了,所以報錯:
 9 # local variable ‘x‘ referenced before assignment.
10 #同理
11 x=6
12 def f2(): 
13     x+=1 #local variable ‘x‘ referenced before assignment.
14 f2()

4.global關鍵字:

當內部作用域想修改外部作用域的變量時,就要用到global和nonlocal關鍵字了,當修改的變量是在全局作用域(global作用域)上的,就要使用global先聲明一下,代碼如下:

1 count = 10
2 def outer():
3     global count
4     print(count)  #正常情況下,count位於global作用域上,在內部作用域裏可以查看但不能修改,如果要修改就需要使用global關鍵字了
5     count = 100  #修改global作用域上的變量
6     print(count)
7 outer()
8 #10
9 #100

5.nonlocal關鍵字:

global關鍵字聲明的變量必須在全局作用域上,不能位於嵌套作用域上,當要修改嵌套作用域(enclosing作用域,外層非全局作用域)中的變量時就需要nonlocal關鍵字:

 1 def outer():
 2     count = 10
 3     def inner():
 4         nonlocal count
 5         count = 20
 6         print(count)
 7     inner()
 8     print(count)
 9 outer()
10 #20
11 #20 

6.總結:

(1)變量查找順序:LEGB,作用域局部>外層作用域>當前模塊中的全局>python內置作用域;

(2)只有模塊、類、及函數才能引入新作用域。其它的代碼塊(如if、try、for等)是不會引入新的作用域的;

(3)對於一個變量,內部作用域聲明了就會覆蓋外部變量。不聲明直接使用,就會使用外部作用域的變量;

(4)內部作用域要修改外部作用域變量的值時,全局變量要使用global關鍵字,嵌套作用域變量要使用nonlocal關鍵字。nonlocal是python3新增的關鍵字,有了這個 關鍵字,就能完美的實現閉包了。

python基礎篇11-函數