1. 程式人生 > >Python之路--函式

Python之路--函式

函式的定義

對程式碼塊和功能的封裝和定義

先來個例子 例如:我們週末幾個朋友要去出遊,那出遊前需要先做個策劃
print('查詢攻略')
print('出行路線')
print('出行計劃')
print('走起')
如果下一次有其他的朋友也想去那個地方出遊,那她得自己重新去策劃,非常麻煩,如果我們能夠把這個計劃系統的告訴她,那她直接執行就行了,非常方便,所以,很多人會寫旅遊攻略,會儲存自己的出行計劃,讓別人去使用,那這個過程就是今天要說的函數了. 我們可以先去定義一個事情或者是功能,等到需要的時候直接去用就好了.那麼這裡定義東西就是一個函式

函式的結構

def 函式名():     函式體   我們使用def關鍵字來定義函式,函式的定義語法,這裡的函式名的命名規則和變數的命名規則一樣

 

def travel(): #定義函式
    print('準備零食')
    print('出行計劃')
    print('集合小夥伴')
    print('走起')

travel()  #呼叫函式

函式的執行流程

第一步:先定義函式 第二步:呼叫函式 第三... 執行函式體(程式碼塊)
1def
travel(): #定義函式 print('準備零食') 4 print('出行計劃') 5 print('集合小夥伴') 6 print('走起') 7 2 travel() #呼叫函式,多次執行就多次呼叫

 

函式的返回值-return

還是上面的例子,我們出遊結束之後,大家都會發朋友圈,來說說對本次出遊的感受,那函式也是一樣,當我們呼叫完之後,可以設定返回值
def travel():
    print('準備零食')
    
print('出行計劃') print('集合小夥伴') print('走起') return ('今天玩的很開心') #反饋結果:今天玩的很開心,這裡返回的是一個元組,多個字串返回的結果就是元組,return對於後面返回的內容是沒有限制的 print(travel()) #檢視結果 print(travel()) 輸出結果: 準備零食 出行計劃 集合小夥伴 走起 今天玩的很開心
關於return,若我們不寫return,那會返回值嗎

def travel():
    print('準備零食')
    print('出行計劃')
    print('集合小夥伴')
    print('走起')

print(travel())
輸出結果:
準備零食
出行計劃     
集合小夥伴
走起
None  #說明我們在不寫return時也會自動預設返回None
那我們寫return,但不寫返回結果,會出現什麼情況呢?

def travel():
    print('準備零食')
    print('出行計劃')
    print('集合小夥伴')
    print('走起')
    return
print(travel())
輸出結果: 
準備零食
出行計劃
集合小夥伴
走起
None #如果有return,但是不寫結果,則返回還是None
如果在return下面再寫內容,會怎樣呢

def travel():
    print('準備零食')
    print('出行計劃')
    print('集合小夥伴')
    print('走起')
    return('今天玩的很開心')
    print('謝謝朋友們的陪伴,希望以後有更多的機會出遊')
print(travel())
輸出結果:
準備零食
出行計劃
集合小夥伴
走起
今天玩的很開心 #return後面的內容都不再執行
總結 所以,return返回值,是將內容返回給呼叫者,也是例子中的travel() 1.可以是任意值,沒有限制,若是多個字串,則返回的是一個元組 2.若return後面什麼都不寫,則預設返回None, 3.若不寫return,函式則預設返回None 4.函式在執行到return時就結束了,return以下的都不會執行,並且終止這個函式

函式的引數

實參

def func(name,age,addr):
    print(f'{name},{age},{addr}')
func('小紅',23,'北京') #這個就是實參

位置引數

def func(name,age,addr):
    print(f'{name},{age},{addr}')
func('小紅',23,'北京') #位置引數,位置必須一一對應 --實參
關鍵字引數

def func(name,age,addr):
    print(f'{name},{age},{addr}')
func(name = '小紅',age = 23,addr = '北京') 
#關鍵字引數,跟format格式化的用法有點相似
混合引數

def func(name,age,addr):
    print(f'{name},{age},{addr}')
func( '小紅',23,addr = '北京') #混合引數
注意:位置引數>關鍵字引數(位置引數一定要在關鍵字引數之前)
def func(name,age,addr):
    print(f'{name},{age},{addr}')
func( '小紅',addr = '北京',23) 
#報錯
位置引數一定要在關鍵字引數之前,不然就會報錯,因為位置引數要求一一對應
如果位置引數已經定義,不可用關鍵字引數再重新定義

def func(name,age,addr):
    print(f'{name},{age},{addr}')
func( '小紅',23,name = '北京') 
報錯
#這樣不行,位置引數已經給name定好了,不能再重定義

行參

def func(name,age,addr):#這個就是形參
    print(f'{name},{age},{addr}')
func('小紅',23,'北京') 
位置引數

def func(name,age,addr):#位置引數,必須要一一對應
    print(f'{name},{age},{addr}')
func('小紅',23,'北京')
預設引數

def func(name,age,addr='北京'):#預設引數,預設北京
    print(f'{name},{age},{addr}')
func('小紅',23)
輸出結果:小紅,23,北京    
def func(name,age,addr='北京'):#預設引數可以通過實參修改
    print(f'{name},{age},{addr}')
func('小紅',23,'南京')
混合引數

def func(name,age,addr='北京'):#這個也是混合引數
    print(f'{name},{age},{addr}')
func('小紅',23,'南京')
注意:位置引數>預設引數(位置引數一定要在預設引數之前)

def func(name,addr='北京',age):
    print(f'{name},{age},{addr}')
func('小紅',23)
報錯,終其原因還是位置引數一一對應的問題

傳參

給函式傳遞資訊的時候將實際引數交給形式引數的過程被稱為傳參 傳參是由實參到形參的過程.

動態引數

動態位置引數 動態位置引數表達形式: *args 如果我們想輸入的內容有很多,但又不太確定時,通過位置引數輸入的話就沒辦法實現,怎麼辦呢,那就用到了動態位置引數,它會把你所想要的東西打包一下,放進去,至於你想放什麼你自己定;就像1個書包一樣,裡面可以放你想放的任何東西.
def func(a,b,*args):--這個就是動態引數的表達形式
    print(a,b,args) #3-6我不確定放什麼就用 *args來聚合打包
func(1,2,3,4,5,6)#3,4,5,6就被我放進去了
輸出結果:1 2 (3, 4, 5, 6) 它是以元組的形式呈現

 對於放的位置而言,也是有要求的

def func(a,b,*args,c = 1):
    print(a,b,c,args) #位置引數>動態位置引數>預設引數
func(1,2,3,4,5,6)
執行結果:
1 2 1 (3, 4, 5, 6)
這是因為位置引數必須是一一對應,所以它必須放在最前面,不然把動態位置放在最前面的話,就全被動態引數給聚合了,那a和b沒有值的話就會報錯了,再說預設引數,如果放在動態引數之前,那它會被3覆蓋掉,每次賦值,都會被覆蓋,就起不到預設引數的作用了

def func(a,b,c = 1,*args):
    print(a,b,c,args)
func(1,2,3,4,5,6)
執行結果:
1 2 3 (4, 5, 6)#每次執行都會被覆蓋,起不到預設值的作用了
再來幾個例子:

def func(a,b,*args):#聚合
    print(a,b,*args)#打散
func(1,2,3,4,5,6)
輸出結果:
1 2 3 4 5 6
lst = [1,2,3,4,5,6]
def func(*args):#聚合
    print(args)
func(*lst)
輸出結果:
(1, 2, 3, 4, 5, 6)
lst = [1,2,3,4,5,6]
def func(*args):#聚合
    print(*args)#打散
func(*lst)#打散
輸出結果:
1 2 3 4 5 6
動態關鍵字引數

動態關鍵字引數(動態預設引數)表達形式: **kwargs 如果我們預設的引數有很多,不確定時,可以通過動態預設引數來實現
def func(a,b,**kwargs):
    print(a,b,kwargs) 
func(1,2,c = 3,d = 4)
輸出結果: #**kwargs輸出的結果以字典的形式呈現
1 2 {'c': 3, 'd': 4}

 

那我們來看看引數的優先順序

def func(a,b,*args,c = 1,**kwargs):
    print(a,b,args,kwargs)
func(1,2,4,5,6,f = 3,d = 4,h = 8)
輸出結果:
1 2 1 (4, 5, 6) {'f': 3, 'd': 4, 'h': 8}
位置引數>動態位置引數>預設引數>動態關鍵字引數(動態預設引數) 如果想接收所有的引數 萬能 無敵
def func(*args,**kwargs):
    print(args,kwargs)
func(1,2,3,4,5,6,a = 3,b = 5)
輸出結果:
(1, 2, 3, 4, 5, 6) {'a': 3, 'b': 5}

 

函式的註釋

自己添加註釋

在程式碼塊最上面輸入'''  ''' ,操作下回車鍵
def func(a,b,*args):
    '''
    
    :param a: 
    :param b: 
    :param args: 
    :return: 
    '''
    print(a,b,args) 
func(1,2,3,4,5,6)

 如果要檢視別人額函式註釋,如果調取

函式名.__doc__

def func(a,b,*args):
    print(a,b,args)
func(1,2,3,4,5,6)
print(func.__doc__)
輸出結果:
  :param a:
    :param b:
    :param args:
    :return:

函式名使用

1.可以檢視函式名的記憶體地址 2.函式名可以當做值去賦給一個變數 3.函式名可以當引數傳遞給函式 4.函式名可以當做函式的返回值 5.函式名可以當做一個元素,存放在一個容器中   檢視函式名的記憶體地址
def func():
    print(1)
print(func)
列印結果:#這個就是func的函式名的記憶體地址
<function func at 0x00000262845D1E18>

 

函式名可以當做值去賦給一個變數

def func():
    print(1)
    return "函式名可以當作值賦給一個變數"
a = func  # func變數名賦給了a,那呼叫a就是在執行這個函式
print(a())
列印結果:
1
函式名可以當作值賦給一個變數
函式名可以當引數傳遞給函式

def f1():
    print(2)
    return '這個是結果'

def func(msg):
    print(1)
    print(msg())
func(f1)#f1作為引數傳給msg,這時f1函式名已經變成msg,然後在func裡執行msg(),將會呼叫f1的結果,所以在進行傳遞引數時,儘量不要加括號,不然會改變執行結果.
輸出結果:
1
2
這個是結果
看一下這種情況

def f1():
    print(2)
def func(msg):
    print(1)
    return msg
print(func(f1))#這個才是正確的使用方式
執行結果:
1
<function f1 at 0x000002ACEF741E18>
函式名可以當做函式的返回值

def func():
    n = 100
    def foo():
        n = 100
        def f1():
            print(n)
            return '結束'
        return f1
    return foo
print(func()()())
輸出結果:
100
結束
def foo():
    print(1)
    return'我想要的結果,別給我改'
def func():
    print(2)
    ret = foo()
    return ret
def func2():
    print(3)
    msg = func()
    return msg
print(func2())
返回結果:
3
2
1
我想要的結果,別給我改

 

函式名可以當做一個元素,存放在一個容器中 lst= [func,f1,f2]可以把多個函式放在一個列表中,如果要一次性呼叫多個函式,可對這個列表進行迴圈,批量調取.