函數:指將一組語句的集合通過一個名字(函數名)封裝起來,要想執行這個函數,只需調用其函數名即可。
def sayhi( ): # 函數名 print('hello world') sayhi( ) #調用函數 , 調用函數時要加上括號(), 不加的話調用的是定義函數名的那個內存地址
示例:
#普通代碼: a,b = 5,8 # 這句話的意思是給兩個變量a,b 分別賦值5和8, 即 a= 8, b=8 c= a**b print(c) #改成用函數寫: def calc(x,y) : res = x**y return res #返回函數執行結果 c= calc(a,b) #結果賦值給c變量 print(c)
特性:
1. 減少重復代碼
2. 使程序變得可擴展
3. 使程序變得易維護
函數參數:
參數能讓你的函數更靈活,還可以根據調用時傳參的不同來決定函數內部的執行流程
形參變量:
只有在被調用時才分配內存單元,在調用結束時,即可釋放所分配的內存單元。因此,形參只在函數內部有效。函數調用結束返回主調函數后則不能再使用該形參變量。
實參:
可以是常量、變量、表達式、函數等,無論實參是何種類型的量,在進行函數調用時,他們都必須有確定的值,以便把這些值傳送給形參,因此應預先用賦值、輸入等辦法使參數獲得確定值。
如:
def calc(x,y): #x和y 就是形參 res = x**y return res c= calc(a,b) #a和b就是實參 print(c)
默認參數:
如下面的程序:
發現country這個參數 基本都是“CN”,我們可以把country設置成默認參數,默認成CN。 這樣,這個參數在調用時你不指定,那就默認是CN,你指定了的話,就用你指定的值。
如:
注:默認參數的位置要放到位置參數(按順序的參數)后面,避免它影響其他的位置參數。
關鍵參數(關鍵字參數):
正常情況下,給函數傳參數要按順序,不想按順序就可以用關鍵參數,只需在調用時指定參數名即可(指定了參數名的參數就叫關鍵參數),但有一個要求,關鍵參數必須放在位置參數(以位置順序確定對應關系的參數)之后。
如下面的程序:
調用時可以這樣:
在調用時course、age、country都指定了,他們就是關鍵參數。指定了之后就可以按照關鍵參數指定的內容來調用函數,而不需要再根據位置來給形參賦值。
但調用時不能這樣:
因為‘PY’指定了參數名course,而22沒有指定參數名,它還是位置參數,關鍵參數必須放在位置參數后面。
也不能這樣:
因為22已經按照位置參數給age賦值成了22, 但后面的age=25又給age賦值了25,不能給同一個參數賦多個值
非固定參數:
如果你的函數在定義時不確定用戶想傳入多少個參數,就可以使用非固定參數。
def stu_register(name,age,*args): # *args會把傳入的參數變成一個tuple(元祖)形式 print(name,age,args)
# 傳遞方式1: stu_register('alex',22) # 輸出結果: # alex 22 () #后面這個()就是args,只是因為沒傳值,所以為空 stu_register('jack',32,'CN','Python') # 輸出結果: # jack 32 ('CN', 'Python') #傳遞方式2: stu_register('jack',32,*['CN','Python']) # 直接把要傳遞的元素放在一個列表(或者元祖)里面,列表(或元祖)前面加 * , 這樣列表(或元祖)中的元素就會傳給*args,並成為*args這個元祖中的元素。 # 輸出結果: # jack 32 ('CN', 'Python') # 這種方法有個需要注意的地方: 列表(或元祖)前面沒有加*。 以下分析這種情況: stu_register('jack',32,['CN','Python']) # 列表前面沒有加*, 這個列表傳遞給*args的時候,會被當成*args這個元祖中的第一個元素。這顯然不是我們想要的,我們想要的是這個列表中的每個元素成為*args這個元祖中的元素。 # 輸出結果: # jack 32 (['CN', 'Python'],) # 列表變成了元祖中的第一個元素。
還有一個是 **kwargs
def stu_register(name,age,*args,**kwargs): # **kwargs會把傳入的多個參數變成一個字典形式 print(name,age,args,kwargs) stu_register('jack',32,'CN','Python') # 輸出結果: # jack 32 ('CN', 'Python') {} # 后面這個{}就是kwargs,只是因為沒有傳值,所以為空 stu_register('jack',32,'CN','Python',gender='Male',province='Shandong') # 輸出結果: # jack 32 ('CN', 'Python') {'gender': 'Male', 'province': 'Shandong'}
注: agrs: arguments ; kwargs: key word arguments。 如果形參中前面出現了 *,就變成元祖; 如果形參前面出現了 ** ,這個形參就變成了字典,也可以把一個字典(如:info)直接傳到kwargs里面, 不過要在函數調用時在字典前面加上 **(如 **info)
另外,位置參數不能放在非固定參數后面,但關鍵參數可以位於*args這種非固定參數后面。
def stu_register(name,age,*args,gender): print(name,age,args,gender) stu_register('jack',32,'CN','Python',gender='male') # 輸出結果: # jack 32 ('CN', 'Python') male
函數返回值:
函數外部的代碼要想獲取函數的執行結果,就可以在函數里用return語句把執行結果返回。(誰調用它就返回給誰)
如:
def stu_register(name,age,course='Python',country='CN'): print('學員信息表'.center(50,'-')) print('Name:',name) print('Age:',age) print('Course:',course) print('Country:',country) if age >= 18: return True else: return False status = stu_register('王山炮',22,course='Python全棧開發',country='JP') #程序在調用完函數stu_register之后會把True或者False的執行結果返回給這個調用函數並賦值給給變量status if status: print('注冊成功') else: print('年齡太小')
注:
-
函數在執行過程中只要遇到return語句,就會停止執行並返回結果,so 也可以理解為 return 語句代表着函數的結束
-
如果未在函數中指定return,那這個函數的返回值為None
- return 只能返回一個值,如果想返回多個值,可以在中間加逗號(,), 但返回的值都在一個元祖中(所以說還是返回一個值),如果return的是一個列表,那返回的結果就是一個列表形式(不再是元祖),元祖return的直接就是元祖
局部變量:
- 在函數中定義的變量稱為局部變量,在程序一開始定義的變量稱為全局變量
- 全局變量的作用域是整個程序,局部變量的作用域是定義該變量的函數
- 當全局變量和局部變量重名時,在定義局部變量的函數內,局部變量起作用;在其他地方全局變量起作用。 如果局部變量跟你全局變量重名並且在函數內這個變量沒有賦值,那么這個局部變量可以調用全局變量的值,也就是說局部變量在函數內的優先級先於全局變量。但是全局變量不能調用局部變量
假如全局變量是 字典、列表、集合,如果在函數內的重名的局部變量有被重新賦值,那么在函數內部這個局部變量使用在函數內被賦的值,並且不會對函數外的這個全局變量的值有影響;如果在函數內這個局部變量沒有被賦值,並且在函數內對它進行了增、刪、修改,那么在函數外部這個全局變量也會被增、刪、修改。但是全局變量如果是字符串、數字,那么就不能通過修改局部變量的方式來改變全局變量。
如果必須想修改全局變量,就用 global, 如:
name= 'alexander' def change_name(): global name # global 在函數內部聲明全局變量 name = 'alex' print(name) change_name() print(name) # 輸出結果: #alex #alex
注:實際項目中盡量不要用global這種方式去聲明全局變量。