1. 程式人生 > 實用技巧 >函式介紹、函式引數

函式介紹、函式引數

一、函式的介紹

1、函式是什麼

想象生活中的例子,修理工需要實現準備好工具箱裡面放好錘子,扳手,鉗子等工具,然後遇到錘釘子的場景,拿來錘子用就可以,而無需臨時再製造一把錘子。

修理工=>程式設計師
具備某一功能的工具
=>函式

要想使用工具,需要事先準備好,然後拿來就用且可以重複使用
要想用函式,需要先定義,再使用

ps:函式就是盛放程式碼的容器
2、為何要用函式

為了解決下述問題:

1)程式碼的組織結構不清晰,可讀性差
2)遇到重複的功能只能重複編寫實現程式碼,程式碼冗餘
3)功能需要擴充套件時,需要找出所有實現該功能的地方修改之,無法統一管理且維護難度極大 
3、如何用函式

3.1、定義的語法

#語法
def 函式名(引數1,引數2,引數3,...):
    '''註釋'''
    函式體
    return 返回的值
 呼叫的語法
#函式名要能反映其意義

3.2、定義函式

發生的事情
1)申請記憶體空間把函式體程式碼放進去
2)將函式記憶體地址繫結給函式名
強調:定義函式只檢測語法,不執行程式碼。也就說,語法錯誤在函式定義階段就會檢測出來,而程式碼的邏輯錯誤只有在執行時才會知道

3.3、函式的呼叫

發生的事情:
1)先通過函式名定位到函式的記憶體地址
2)函式記憶體地址()->觸發函式體程式碼的執行
強調:呼叫函式才會執行函式體程式碼
例1:
def func():
	print(11111      #False 語法錯誤

例2:
def func():
    print(1111)
    x
    print(2222)
func()          # False 邏輯錯誤 

例3
def bar():
	print('from bar')
def foo():
	print('from foo')
	bar()
foo()
    =================
def foo():
    print('from foo')
    bar()
def bar():
	print('from bar')
foo()                            #Fales 反了,要先定義,再呼叫

3.4、定義函式的三種形式

  1. 無參:應用場景僅僅只是執行一些操作,比如與使用者互動,列印
ef say():
    print('========')
    print('welcome to here')     
    print('========')
say()
def login():
    inp_name = input("username>>>: ").strip()
    inp_pwd = input("password>>>: ").strip()
    if inp_name == "egon" and inp_pwd == "123":	
		print('login successful')
    else:
    	print("username or password error")
login()
  1. 有參:需要根據外部傳進來的引數,才能執行相應的邏輯,比如統計長度,求最大值最小值
def max2(x,y)     
	if x > y:        
		print(x)
    else:
    	print(y)
max2(10,20)
  1. 空函式:設計程式碼結構
def login():
	pass
結論:

定義時無參,意味著呼叫時也無需傳入引數

定義時有參,意味著呼叫時則必須傳入引數

3.5、呼叫函式的三種形式

1)語句形式

len('hello')    /     foo( )
  1. 表示式形式
res=len('hello')*10
print(res)
  1. 可以當做引數傳給另外一個函式
print(len("hello"))

二、函式引數

總體分為兩大類:

  • 形參:在函式定義階段括號內指定的引數,稱之為形式引數,簡稱形參-》變數名

  • 實參:在函式呼叫階段括號內傳入的值,稱之為實際引數,簡稱實參-》變數的值

形參與實參的關係是:在呼叫函式時,實參值會繫結給形參名,在函式呼叫完畢後解除繫結

形參系列-----

1、位置形參:在定義函式時,按照從左到右的順序依次定義的變數名,稱之為位置形參

​ 特點:每次呼叫,必須被賦值

ef func(name,age):
    print(name)
	print(age)
func(1,2)

2、預設形參:在定義函式時,就已經為某個形參賦值了,稱之為預設形參

​ 特點:呼叫函式時,可以不用為其賦值

def func(name,age=18):
	print(name)
    print(age)
func("egon")
func("egon",19)  #  19  以呼叫的為準

& 注意 : 可以混用位置形參與預設形參,但是

​ 1)、位置形參必須在前面

​ 2)、預設形參的值通常應該是不可變型別

​ 3)、預設形參的值是在函式定義階段賦值的

ef func(name,hobby,hobbies = None):    
	if hobbies is None:       
		hobbies = []   
	hobbies.append(hobby)   
	print('%s的愛好是%s' %(name,hobbies))
func('egon','read')
func('tom','play')
func('jack','music')
func('lili','eat',["movie"])
m=1111
def func(x,y,z=m):  
    print(x)    
    print(y)   
    print(z)
    m=666
func(1,2)      #   m仍然是1111,以先定義的為準

實參系列-----

1、位置實參:在呼叫函式時,按照從左到右的順序依次傳入的值,稱之為位置實參

​ 特點:按照位置為形參賦值,一 一對應

def res(name,age)
	...
res('egon',18)

2、關鍵字實參:在呼叫函式時,按照key=value的形式傳值,稱之為關鍵字實參

​ 特點:可以打亂順序,但是仍然能夠指定道姓地為指定的形參賦值

def res(name,age)
	...
res(age=18,name="egon")

& 注意:可以混用位置實參與關鍵字實參,但是

​ 1)、位置實參必須在關鍵字實參的前面

​ 2)、不能為同一形參重複賦值

def res(name,age)
	...
func("egon",age=18)   # True
func(age=18,"egon")   # 語法錯誤
def foo(x,y,z):
	pass
foo(1,y=2,3)   # 錯誤
foo(1,y=2,z=3,x=4)  # 錯誤,不能重複呼叫

可變長系列-----

可變長引數指的是在呼叫函式時,傳入的實參個數不固定,對應著必須有特殊形式的形參來接收溢位的實參

實參無非兩種形式======>

​ 溢位的位置實參--->*

​ 溢位的位置關鍵字實參--->**

一.. ==============*與**在形參中是一種彙總行為=====================

1、*在形參中的應用: *會將溢位的位置實參合併成一個元組,然後賦值給緊跟其後的那個形參

def func(x,*args):     # y = (2,3,4,5) 
	print(x)    
	print(args)
func(1,2,3,4,5)
def my_sum(*args):  
	res = 0  
    for i in args:       
    	res += i   
        print(res)
my_sum(1,2)         結果為 1+2=3

2、2個* . 在形參中的應用:* *會將溢位的關鍵字實參合併成一個字典,然後賦值給緊跟其後的那個形參名

def func(x,**kwargs):      # kwargs = {"a":2,"c":4,"b":3}
    print(x)
    print(kwargs)
func(1,a=2,b=3,c=4)
二 ..==============*與**在實參中是一種打散行為=====================
1、*在實參中的應用:*後可以跟可以被for迴圈遍歷的任意型別,*會將緊跟其後的那個值打散成位置實參
def func(x,y,z):   
    print(x)    
    print(y)    
    print(z)
func(*[11,22,33])    # 11,22,33
func(*"hel")         #  h,e,l
unc(*{"x":111,"y":2222,"z":3333})         #     x,y,z  
2、**在實參中的應用:**只能跟字典型別,**會將字典打散成關鍵字實參
def func(x,y,z):   
    print(x)    
    print(y)   
    print(z)
func(**{"x":111,"y":2222,"z":3333})  
def index(x,y,z):
	print(x,y,z)
def wrapper(*args,**kwargs):  # args=(1,2,3,4,5,6)  kwargs={"a":1,"b":2,"c":3}#     		index(*args,**kwargs)  # index(*(1,2,3,4,5,6),**{"a":1,"b":2,"c":3})#     #                        index(1,2,3,4,5,6,a=1,b=2,c=3)# 
wrapper(1,2,3,4,5,6,a=1,b=2,c=3)
wrapper(1,y=2,z=3)
 瞭解(**):命名關鍵字形參: 在*與**中間的形參稱之為命名關鍵字形參    
 特點: 必須按照key=value的形式傳值
 def func(x,m=333,*args,y=222,z,**kwargs):   
     print(x)  
     print(args)    
     print(y)    
     print(z)   
     print(kwargs)
 func(1,2,3,z=4,a=1,b=2,c=3)