函數
python 函數
由若干語句組成的語句塊、函數名稱、參數列表構成,他是組織代碼的最小單元
完成一定的功能
函數的作用:
結構化編程對代碼的最基本的封裝,一般按照功能組織一段代碼
封裝的目的是為了復用,減少冗余代碼
代碼更加簡潔美觀、可讀易懂
函數的分類:
內建函數:如max(),reversed()等
庫函數:如math.ceil()
函數 及 變量
#形參:
特點:1、不占內存空間,只有調用函數的時候傳入一個值給它,它才占用內存空間。
2、而且函數運行完后形參就會被釋放掉。
return 返回多個的時候,會變成一個元組
位置參數:要求函數按照順序 一 一 對應,
關鍵字參數:z=1,x=2,y=3 特點:不用再考慮位置了
位置參數和關鍵字參數混合時原則:位置參數必須在關鍵字參數的左邊。
默認參數:在定義的時候先配置好。
為什么要使用函數:
1.減少重復代碼
2.保持一致性,易維護
3.可擴展性

- 函數名就是標識符,命名要求一樣
- 語句塊必須縮進,約定4個空格
- python 的函數沒有return語句,隱式會返回一個None值
- 定義中的參數列表成為形式參數,只是一種符號表達,簡稱形參
- 調用:
- 函數定義,只是聲明了一個函數,它不會被執行,需要調用
- 調用的方式,就是函數名加上小括號,括號內寫上參數
- 調用時寫的參數是實際參數,是實實在在傳入的值,簡稱實參
函數參數:
參數調用時傳入的參數要和定義的個數匹配(可變參數例外)
位置參數:
def ff(x,y,z) 調用時使用 ff(1,3,5)
按照參數定義順序傳入實參
關鍵字參數:
def f(x,y,z) 調用使用f(x=1,z=5,y=3)
使用形參的名字來傳入實參的方式,如果使用了形參的名字,那么傳參順序就可和定義順序不同
要求:位置參數必須在關鍵字參數之前傳入。位置參數是按位置對應的。
函數參數默認值
參數默認值:
定義時,在形參后跟上一個值,叫做默認值(缺省值)
作用:
參數的默認值 可以在未傳入足夠的實參的時候,對沒有給定的參數賦值為默認值。
參數非常多的時候,並不需要用戶每次都輸入所有的參數,簡化函數調用。
可變參數:
一個形參可以匹配任意個參數
1、 位置參數的可變參數:
在形參前使用* 表示該形參是可變參數,可以接收多個實參
收集多個實參為一個tuple。
注:位置可變參數不能傳入keyword實參。不支持。

2、關鍵字參數的可變參數:
形參前使用 ** 符號,表示可以接受 多個關鍵字參數
收集的實參名稱和值 組成一個字典
3、keyword-only 參數 關鍵字參數
如果一個星號參數后,或者一個位置可變參數后, 出現的普通參數,實際上已經不是普通的參數了,而是keyword-only參數
下圖報錯: 可以理解為kwargs 會截獲所有的關鍵字參數,就算你寫了x=5,x也永遠得不到這個值,所以語法錯誤。
特殊寫法:
def fn(*,x,y): # * 什么意義都沒有,只是讓x,y 都必須為keyword-only參數。
print(x,y)
往往可變參數都會跟着默認值。
1、創建函數
def 函數名稱(形式參數):
函數體
2、返回值 return
return "111"
2.1 return 什么就返回什么,沒有跟數,就返回None
2.2 一旦遇到return 函數內部的 return以下代碼就不再執行。
3、 執行函數
函數名(實際參數)
2.1 注:形參有即可要加幾個實參,默認是按照順序一一對應的,數量要一致
4、指定參數
在指定參數時,傳入實參,可以不按照順序,需要指定等於誰,如下圖
函數可以有默認參數(有默認值得參數一定要放在參數的尾部)
callable(add)
True # 如果是True 說明add 是可調用的函數
5、動態參數一: def aa(*a) 所有的參數為一個元組,傳參數的時候只能按照順序來傳
def aa(*name):
print(name,type(name))
aa(11,22,33,444)
# (11, 22, 33, 444) <class 'tuple'> # 元組,傳的參數變成元組的元素了
動態參數二: def bb(**a)所有參數必須為a=xxx, b=xxx,
def bb(**name):
print(name,type(name))
bb(k1=11,k2=22,k3=33,k4=444)
# {'k2': 22, 'k1': 11, 'k3': 33, 'k4': 444} <class 'dict'> #字典 ,傳的參數變成字典的元素了
動態參數三: *a 和**a的結合
如果傳的是f1(11,22,33,44) 會自動識別為*a這個參數
如果傳的是f1(k1=123,k2=456) 會自動識別為**a 這個參數
一般定義為:一個*就寫成 *args
兩個*就寫成**kwargs
6、動態參數傳入 列表、字典、元組
def f1(*args):
def f1(**kwargs):
## 一個星的時候
def f1(*args):
# 元組 ([11, 22, 33, 44], 123)
print(args,type(args))
li = [11,22,33,44]
tu = (22,33,44,55,66)
f1(li,123) # 不加*的將整個列表都加到參數里
# ([11, 22, 33, 44], 123) <class 'tuple'>
f1(*li,123) # 加上*后,將列表的每一個元素都放到參數里
# (11, 22, 33, 44, 123) <class 'tuple'>
f1(tu) # ((22, 33, 44, 55, 66),) <class 'tuple'>
f1(*tu) # (22, 33, 44, 55, 66) <class 'tuple'>
## 兩個星的時候
def f1(**kwargs):
print(kwargs,type(kwargs))
dic = {"k1":123,"k2":456}
f1(kk=dic) # {'kk': {'k2': 456, 'k1': 123}} <class 'dict'>
f1(**dic) # {'k2': 456, 'k1': 123} <class 'dict'>
可變參數總結:
- 有 位置可變參數(*args) 和 關鍵字可變參數(**kwargs)
- 位置可變參數在形參前使用一個星號*
- 關鍵字可變參數在形參前使用兩個星號**
- 位置可變參數和關鍵字可變參數都可以收集若干個實參,普通參數需要放到參數列表前面,位置可變參數需要在關鍵字可變參數之前
----------------- 參數解構 --------------------------
參數解構:
給函數提供實參的時候,可以在集合類型前使用 * 或者 ** ,把集合類型的結構解開,提取出所有元素作為函數的實參。
非字典類型使用 * 結構成位置參數
字典類型使用 ** 結構成關鍵字參數
提取出來的元素數目要和參數的要求匹配,也要和參數的類型匹配
參數解構和可變參數:
給函數提供實參的時候,可以在集合類型前使用 * 或者 ** ,把集合類型的結構解開,提取出所有元素作為函數的實參。
## 全局變量和局部變量
7.1 全局變量:
一般命名規則:大寫
修改:global
所有人都可以使用,但是不能修改。如果要修改,請加上關鍵字global
7.2 局部變量:
在函數中定義的變量,只能在函數中使用
一般命名規則:小寫
注:如果如果想要在局部變量修改全局變量要使用關鍵字:
全局變量 :global
上一級變量 :nonlocal
global使用原則;
1、外部作用域變量會在內部作用域可見,但是一般在內部作用域中直接使用,因為函數的
目的就是為了封裝,盡量與外界隔離。
2、如果函數需要使用外部全局變量,請使用函數的形參傳參解決
3、一句話:不要輕易使用global,這樣會破壞分裝。
閉包:
自由變量: 未在本地作用域中定義的變量。例如定義在內存函數外的外層函數的作用域中的變量
閉包:就是一個概念,出現在嵌套函數中,指的是內層函數引用到了外層函數的自由變量,就形成了閉包。
函數參數傳遞引用:
舉例一:
def f2(arg):
if len(arg) > 2:
del arg[2:]
li = [11,22,33,44,55]
f2(li)
print(li)
# [11, 22]
舉例二:
說明:一旦變量遇到變量遇到等號
如:name = xxx
如果xxx 是一個真實的值,那么就會在內存中去創建這個值,name 就會等於這個值。
如果xxx 是一個變量,變量就指向另一個值,
def f3(arg):
arg = 123
li = [1,2,3,4]
f3(li)
print(li)
# [1, 2, 3, 4]
前向引用: