1. 程式人生 > >函式引數詳解

函式引數詳解

形參與實參
    形參即形式引數,就是在定義函式時括號中指定的引數,本質就是一個名字
    實參即實際引數,指的是在呼叫函式的時候傳入的引數,是一個實際的值
在呼叫函式時就會自動把形參(變數名)和實參(值)進行繫結
函式呼叫結束之後繫結關係就解除了
    
def func1(a,b):#a,b就是形參 a=1,b=2
print(a)
print(b)
func1(1,2)#1,2就是實參


位置引數
    根據呼叫階段 引數分為兩類 形參和實參
    所以對應的位置引數也有位置形參和位置實參
位置,其實指的是順序,從左往右來定義的引數就是位置(順序)引數
需要注意的是:
    位置形參的數量與位置實參的數量必須一致,不能多傳,也不能少傳
    實參會按照傳入的位置一次賦值給形參
    位置形參   位置實參
def func(a,b,c):#abc都是位置形參
print(a,b,c)
func(1,2,3)#1,2,3都是位置實參


def register(name,password,sex):
    print('mynameis% my passwordis%my age is%') %(name,password,sex)
register('rose','123','woman')

關鍵字引數 
    關鍵字實參
    在呼叫函式時,指名道姓的為形參賦值就稱為關鍵字引數
其優點是:
    可以打破傳入蠶食的順序 可以不與形參順序相同
注意:
  1.不管以什麼樣的方式傳值,每一個形參都必須被傳值
  2.關鍵字引數必須位於未知引數的後面
  3.不能為同一個引數傳多次值
  4.使用關鍵字傳參時,實參的名字必須與形參的名字匹配
  
  到底是位置引數還是關鍵字引數 由實參決定
  
def func(a,b,c):
    print(a)
    print(b)
    print(c)
#func(1,2,c=3)與位置引數沒區別
#func(c=1,2,3)語法錯誤 關鍵字引數出現在了未知引數前面
#func(a=1,b=2,c=3) 可以打破位置引數的順序限制

def register(name,pwd):
   print('name is',name)
   print('password is',pwd)
register(pwd='123',name='bgon')

可以不用完全按照順序來傳值
open ('今日內容',encoding='utf-8')

預設形參
    在定義時,就已經為形參制定了一個值,那這個形參就稱之為預設形參
特點:
    在呼叫時,可以不用為預設形參傳值,這樣在函式體中使用預設形參時,使用時就是預設值
    當然也可以傳值,這樣的話內部使用的就是你傳入的值
使用場景:
    當函式中的某一形參經常出現重複的值時,就可以將其定義為預設形參
可以簡化呼叫程式碼
需要注意
      1.預設形參必須放在非預設形參後面
      2.預設形參的值在定義時就已經固定了
      3.不應該將預設形參的預設值設定為一個可變型別
      會導致 每次函式呼叫都共用同一個預設引數,我們應該將函式設計為一個獨立的功能,每次呼叫互不干擾
      只能是int float str tuple
      
def reg1(name,sex,hobby=['play','music']):
    print(name,sex)
    print(hobby)
reg1('bgon','man',['play','music','movie'])
reg1('cgon','man',['music','sleep'])  

def reg1(name,sex,hobby):
    print(name,sex)
    print(hobby)
reg1('bgon','man',['play','music','movie'])
reg1('cgon','man',['music','sleep'])  


可變長引數指的是,可以傳任意個數的實參
傳入實參是為了給形參來使用,那就意味著,必須讓形參也具備可以接受任意個數的引數的能力
也就是*和**  
   帶*的形參
    帶*的形參表示可以接受任意個數的實參,這些接受到的實參會被打包成元組型別
    形參的名字可以隨意,但是建議用args 是arguments的縮寫
    iterable 可迭代的 只要是可以被for in 迴圈使用的都是可迭代 字串 列表 元組 字典 集合
   帶*的實參
    在實參前面加*,會自動將*後的值,打散('abc'打散 成了'a','b','c')
   帶*的實參 不能接受關鍵字的實參
   
def func(*abc):
    print(abc)
    pass
func(1)
func(1,2)
func(1,2,3)
    
位置形參與可變長形參混合使用***
當可變長形參,出現在了位置形參的前面時,那麼後面的位置形參必須以關鍵字實參來傳入
def func(*args,a,b):
    print(a,b,args)
func(1,2,3,a=4,b=5)
當可變長形參出現在位置形參後面,會先按照順序給前面的位置形參賦值,最後剩餘的就賦值給可變長args
def func(a,b,*args):
    print(a,b,args)   
func(1,2,3,4,5)

**的使用
    形參中如果帶有**,會把關鍵字實參打包成字典型別傳入
    只能接收多出來的關鍵字實參
 **不能接受位置實參

def func(**b):
    print(b)
func(1)

先為前面的位置形參賦值,後續的多餘的關鍵字引數賦值給**
def func(a,c,**b):
    print(a,c)
    print(b)
func(1,s=100,c='abc')



實參中帶**,會把**後的字典(也必須是字典型別)打散,成關鍵字實參(**{'a':1}) 打散為a=1
def func(name,sex):
    print(name,sex)
func(**{'name':'rose",'sex':'woman'})#func(name='rose')


# print(**{'name':'rose"}) 錯誤

*和**可以為函式預留擴充套件空間,後期可以根據需求增加引數,而且舊的函式呼叫方式也不會出現問題
簡單的說就是提高函式的擴充套件性

寫一個帶有可變長的位置形參函式
def func(name,pwd,*kwargs)      #******
    if name == 'bgon' and pwd =='123':
        if 'phone' in kwargs:
            if kwargs['phone']=='110'
               print('登陸成功!')
        else:
            print('傳入手機號驗證!')
    else:
        print('登入失敗!')
        
func('bgon','123',phone='110')
    
# 該方式可以接受任意個數的位置實參和關鍵字實參,
# 但要注意順序,位置實參必須在關鍵字之前

def inner(name,sex,age):
    print(name,sex,age)

def outer(*args,**kwargs):
    print(args)
    print(kwargs)
    inner(*args,**kwargs) # inner(1,2,3,a=10,b=20)

outer(1,2,3,100,a=10,b=20)

# 上述寫法 可以將outer接收到的所有引數 原模原樣的傳給inner函式