一、 函式的引數
1、形參角度:
-
萬能引數:
動態引數分為兩種:動態接受位置引數 *args,動態接收關鍵字引數:**kwargs.
動態接收位置引數:*args
def eat(*args):
print('我請你吃:',args)
eat('蒸羊羔兒','蒸熊掌','蒸鹿尾兒','啥訓鴨','燒雛雞','燒子鵝')
# 運行結果:
#我請你吃: ('蒸羊羔兒', '蒸熊掌', '蒸鹿尾兒', '啥訓鴨', '燒雛雞', '燒子鵝')
? args就是一個普通的形參,但是如果你在args前面加一個,那么就擁有了特殊的意義,他將所有的位置引數聚合成一個元組賦值給了args
練習:傳入函式中數量不定的int型資料,函式計算所有數的和并回傳,
def eat(*args):
n = 0
for i in args:
n += i
return n
print(eat(1,2,3,4,5,6))
動態接收位置引數: **kwargs
? 函式定義時:**將所有的關鍵字引數聚合到一個字典中,將這個字典賦值給了kwargs
def func(**kwargs):
print(kwargs)
func(name='alex',age=18,sex='boy')
結果:{'name': 'alex', 'age': 18, 'sex': 'boy'}
def func(*args,**kwargs):
print(args) # ('蒸羊羔兒', '蒸熊掌', '蒸鹿尾兒')
print(kwargs) # {'name': 'mrxiong', 'sex': '男'}
func('蒸羊羔兒', '蒸熊掌', '蒸鹿尾兒',name='mrxiong',sex='男')
2、形參角度的引數的順序
位置引數必須在前面,即 :位置引數,默認引數,*args動態引數必須在位置引數后面
def fun(a,b,*args,sex='男'):
print(a,b)
print(sex)
print(args)
fun(1,2,3,4,5,6,7,sex='女')
所以*args一定要在位置引數與默認值引數中間:位置引數,*args,默認引數,
def fun(a,b,*args,sex='男',**kwargs):
print(a,b)
print(sex)
print(args)
print(kwargs)
fun(1,2,3,4,5,6,7,sex='女',name='Alex',age=12)
所以截止到此:所有形參的順序為:位置引數,*args,默認引數,**kwargs,
3、形參角度第四個引數:僅限關鍵字引數
def fun(a,b,*args,sex='男',c,**kwargs):
print(a,b)
print(sex)
print(args)
print(c)
print(kwargs)
fun(1,2,3,4,5,6,7,sex='女',name='Alex',age=12,c=6666)
上例中c是僅限關鍵字引數,它必須要放在*args和**kwargs之間
形參角度的所有形參的最終順序為:位置引數,*args,默認引數,僅限關鍵字引數,**kwargs,
4、在函式的呼叫時,*代表打散
*args打散
def fun(*args):
print(args)
fun(*[1,2,3],*[22,33,44])
輸出結果:(1, 2, 3, 22, 33, 44)
**kwargs打散
def fun(*args,**kwargs):
print(args)
print(kwargs)
fun(**{'name':'mrxiong'},**{'age':18})
**在函式定義的時候代表聚合, 在函式執行的時候代表打散
二、名稱空間,作用域
? Python代碼運行的時候遇到函式是怎么做的,從Python解釋器開始執行之后,就在記憶體中開辟里一個空間,每當遇到一個變數的時候,就把變數名和值之間對應的關系記錄下來,但是當遇到函式定義的時候,解釋器只是象征性的將函式名讀如記憶體,表示知道這個函式存在了,至于函式內部的變數和邏輯,解釋器根本不關心,
等執行到函式呼叫的時候,Python解釋器會再開辟一塊記憶體來儲存這個函式里面的內容,這個時候,才關注函式里面有哪些變數,而函式中的變數回儲存在新開辟出來的記憶體中,函式中的變數只能在函式內部使用,并且會隨著函式執行完畢,這塊記憶體中的所有內容也會被清空,
? 我們給這個‘存放名字與值的關系’的空間起了一個名字-------命名空間,
? 代碼在運行開始,創建的存盤“變數名與值的關系”的空間叫做全域命名空間;
? 在函式的運行中開辟的臨時的空間叫做區域命名空間也叫做臨時名稱空間,
? 現在我們知道了,py檔案中,存放變數與值的關系的一個空間叫做全域名稱空間,而當執行一個函式時,記憶體中會臨時開辟一個空間,臨時存放函式中的變數與值的關系,這個叫做臨時名稱空間,或者區域名稱空間,
? 其實python還有一個空間叫做內置名稱空間:內置名稱空間存放的就是一些內置函式等拿來即用的特殊的變數:input,print,list等等,所以,我們通過畫圖捋一下:

那么這就是python中經常提到的三個空間,
總結:
- . 全域命名空間--> 我們直接在py檔案中, 函式外宣告的變數都屬于全域命名空間
- . 區域命名空間--> 在函式中宣告的變數會放在區域命名空間
- . 內置命名空間--> 存放python解釋器為我們提供的名字, list, tuple, str, int這些都是內置命名空間
1、加載順序
內置名稱空間-------->全域命 名空間----------->區域命名空間
2、取值順序
取值順序(就近原則),單向不可逆
(從區域找)區域名稱空間------->全域名稱空間------>內置名稱空間

3、作用域
全域作用域:包含內置名稱空間、全域名稱空間
區域作用域 :區域名稱空間
區域作用域可以參考全域作用域的變數
報錯示例:
count=1
def func():
count+=2
print(count)
func()
輸出結果報錯:
UnboundLocalError: local variable 'count' referenced before assignment
因為:區域作用域不能改變全域作用域的變數,當python解釋器讀取到區域作用域時,發現了你對一個變數進行修改操作,解釋器會認為你在局己經定義過這個區域變數,它就從區域找這個區域變數,所以報錯了
三、關鍵字:global、nonlocal
global
利用global在區域作用域也可以宣告一個全域變數,
def func():
global a
a = 3
func()
print(a)
所以global關鍵字有兩個作用:
1,宣告一個全域變數,
2,在區域作用域想要對全域作用域的全域變數進行修改時,需要用到 global(限于字串,數字),
nonlocal
? nonlocal是python3x新加的功能,與global用法差不多,就是在區域作用域如果想對父級作用域的變數進行改變時,需要用到nonlocal,當然這個用的不是很多,了解即可,
def add_b():
b = 42
def do_global():
b = 10
print(b)
def dd_nonlocal():
nonlocal b
b = b + 20
print(b)
dd_nonlocal()
print(b)
do_global()
print(b)
add_b()
nonlocal關鍵字舉例
nonlocal的總結:
1,不能更改全域變數,
2,在區域作用域中,對父級作用域(或者更外層作用域非全域作用域)的變數進行參考和修改,并且參考的哪層,從那層及以下此變數全部發生改變,
另一作用:
glbals()、 locals()
globals() 回傳的是字典,字典里面的鍵值對,全域作用域的所有內容
locals() 回傳的是字典,字典里面的鍵值對,當前作用域的所有內容
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/108995.html
標籤:Python
上一篇:Celery淺談
