Python中的函數(shù)

Python中的函數(shù)

定義/調(diào)用

def sayHi():
    print('hello,function in Python')

sayHi()

注意Python中沒有JS一樣的聲明前置,所以定義必須要在調(diào)用之前

函數(shù)中的參數(shù)

def say(str):
    print(str)

say('hello, this is argument')

對于Python中的函數(shù)參數(shù),定義幾個就傳幾個參,這個很好理解。但是也有一些高級的或者是簡化的參數(shù)用法:

  • 默認(rèn)參數(shù):
def powerNum(num,pow=2):
    res = 1
    while pow>0:
        pow -= 1
        res = res * num
    return res

print( powerNum(5) ) # 25  不傳第二參數(shù)的話,默認(rèn)使用pow=2來進(jìn)行計算
# 等價于 print( powerNum(5,2) )

print( powerNum(2,3) ) # 8

默認(rèn)參數(shù)使用的時候,一般放在必選參數(shù)后面,如果有多個默認(rèn)參數(shù),前面的想使用默認(rèn)值,后面的想自行賦值的話,可以這么寫:

def intro(name,age=18,word='hello,nice 2 meet u'):
    print('name:%s,age:%d,%s'%(name,age,word))

# 我們現(xiàn)在想使用默認(rèn)的age,但是想自行賦值word

intro('DeeJay',word='this is DeeJay') # name:DeeJay,age:18,this is DeeJay

#  這么一來就使用了默認(rèn)的age并且自定義了word

值得注意的是,默認(rèn)參數(shù)必須指向不變的對象,如果是個可變量的話,每次調(diào)用,默認(rèn)函數(shù)指向的那個變量的也會改變

def pushEndToList(li = []):
    li.append('END')
    print(li)

pushEndToList() # ['END']
pushEndToList() # ['END', 'END']
pushEndToList() # ['END', 'END', 'END']

# 可以看到 默認(rèn)參數(shù)li=[] 指向的不是一個不變的對象,
# 調(diào)用函數(shù)的時候,li指向的對象的值變了,那么再次調(diào)用的時候li的值就已經(jīng)改變了
# 所以,默認(rèn)參數(shù), 必須要指向一個不變的對象(比如None)
  • 可變參數(shù)
    有時候我們定義函數(shù)的時候并不清楚到底需要多少個參數(shù),就可以使用可變參數(shù),使參數(shù)的個數(shù)不固定
def sum(*num):
    print(num)
    print( type(num) ) # <class 'tuple'>
    res = 0
    for number in num:
        res += number
    return res

sum(1,2,3,4) # (1,2,3,4)

res = sum(1,2,3,4)
print(res) # 10

可變參數(shù)的用法已經(jīng)很清楚了,另外我們可以看到,這個可變參數(shù)其實是一個tuple

  • 關(guān)鍵詞參數(shù)
def keywordFunction(name,age,**kw):
    print('%s,%s,%s'%(name,age,kw))


keywordFunction('DeeJay',22) # DeeJay,22,{} 可以不傳關(guān)鍵詞參數(shù)

keywordFunction('Yang',23,city='xian') # Yang,23,{'city': 'xian'}

keywordFunction('Wen',23,city='xian',job='frontEnd') # Wen,23,{'city': 'xian', 'job': 'frontEnd'}

關(guān)于函數(shù)的參數(shù)問題,我們來看一個綜合的例子:

def fn(a,b,c=100,*args,**kw):
    print(a)
    print(b)
    print(c)
    print(args)
    print(kw)

fn(1,2,3,4,5) # 1 2 3 (4,5) {}
# 這個很好理解,因為沒有傳入kw,默認(rèn)參數(shù)c被賦值了3,剩下的被當(dāng)成args構(gòu)造出一個元祖


fn(1,2,3,4,5,name='DeeJay',age=21) # 1 2 3 (4,5) {'name': 'DeeJay', 'age': 21}
# 這次傳入了kw


# 然后來看一個例子,
A = (4,5)
B = {'name': 'DeeJay', 'age': 21}

# 定義了A和B,然后傳給fn()
fn(1,2,3,A,B) 
# 輸出結(jié)果為: 
# args == ((4, 5), {'name': 'DeeJay', 'age': 21})
# kw == {}

# 出現(xiàn)上述結(jié)果的原因是,沒有按照格式來進(jìn)行傳入kw,即按照key=value的形式傳入
# 所以A和B都被當(dāng)成了args,那么如果我們想讓A被當(dāng)成args,B作為kw,可以這樣寫:

fn(1,2,3,*A,**B) # 此時args == (4,5) kw == {'name': 'DeeJay', 'age': 21}
# 這種方法成為拆包 

注意最后的fn(1,2,3,*A,**B)的寫法,拆包的作用就是在傳參的時候,將變量分解作為參數(shù)給函數(shù)。

函數(shù)的return值

在Python中,函數(shù)如果沒有顯示的寫明return值,那么函數(shù)默認(rèn)return None

此外直接寫return也等價于return None

對于想返回多個值的函數(shù),可以將多個值組合為一個list或者tuple等返回。

def fn():
    a = 10
    b = 20
    c = 30
    return a,b,c

res = fn()
print(res) # (10, 20, 30) 是一個tuple

局部變量和全局變量

Python中的函數(shù)中定義的變量為局部變量:

num = 99

def fn():
    num = 100

def printNum():
    print(num)

fn()
printNum() # 99

上述例子中,已經(jīng)在全局環(huán)境中定義了num,所以在fn()中是在拘捕作用域中定義了一個局部變量num,而不是修改全局中的num,二者僅僅是變量名相同。

如果想要在fn()中修改全局的num,那么需要這么寫:

num = 99

def fn():
    global num # 表明在內(nèi)部作用域中沒有定義新的局部變量num,這邊的num就是全局變量
    num = 100

def printNum():
    print(num)

fn()
printNum() # 100 此時輸出的就是修改過后的全局變量num 為100

上述例子使用global來聲明是操作一個全局變量而不是需要重新定義一個局部變量

但是也有例外,對于dict和list,其實可以不寫global,程序仍然會去使用全局變量,而不是默認(rèn)先定義一個局部變量:

# 對于dict和list,如果是全局變量 其實可以不用寫global,
# 也會默認(rèn)使用全局的,而不是先定義一個

di = {'name':'DeeJay'}
li = [1,2,3]

def fn1():
    # 這邊沒有聲明global
    di['age'] = 21
    li.append(4)

def fn2():
    print(di)
    print(li)

fn1()
fn2() # {'name': 'DeeJay', 'age': 21} [1, 2, 3, 4]
# 直接改變了全局中的di和li

Python中的遞歸

Py中的遞歸沒什么特別的地方,寫個階乘函數(shù)了解一下:

def factorial(n):
    if(n == 1):
        return 1
    return n * factorial(n-1)

res = factorial(4)
print(res)

匿名函數(shù)lambda

  • 語法
    lambda args: expression
lambda x: x*x

上述例子, lambda x:x是參數(shù),后面的x*x是作為函數(shù)return的值。

  • 用法

使用匿名函數(shù)來進(jìn)行list.sort()

list.sort()接受一個值為一個函數(shù)的key,將這個函數(shù)的返回值作為排序的依據(jù),例子:

li = [1,-3,2]

li.sort(key=abs)

print(li) # [1, 2, -3]

# 將abs()的返回值作為排序依據(jù)

搭配匿名函數(shù)也可以進(jìn)行排序:

li = [
    {'name': 'xiaohong','age': 21},
    {'name': 'xiaohong','age': 30},
    {'name': 'xiaohong','age': 24},
    {'name': 'xiaohong','age': 23},
]

# 現(xiàn)有如上list,想根據(jù)其中每個元素的age屬性來進(jìn)行排序:

li.sort(key=lambda person: person['age'])

print(li) # 輸出:
# [{'name': 'xiaohong', 'age': 21}, 
# {'name': 'xiaohong', 'age': 23}, 
# {'name': 'xiaohong', 'age': 24}, 
# {'name': 'xiaohong', 'age': 30}]

匿名函數(shù)也可以作為參數(shù)傳入別的函數(shù)進(jìn)行調(diào)用:

def fn(a,b,fn):
    return fn(a,b)

res = fn(1,2,lambda num1,num2: num1 + num2)
print(res) # 3

以上就是匿名函數(shù)的基本用法

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 〇、前言 本文共108張圖,流量黨請慎重! 歷時1個半月,我把自己學(xué)習(xí)Python基礎(chǔ)知識的框架詳細(xì)梳理了一遍。 ...
    Raxxie閱讀 19,567評論 17 410
  • 1.函數(shù)的介紹 為什么要有函數(shù)?因為在平時寫代碼時,如果沒有函數(shù)的話,那么將會出現(xiàn)很多重復(fù)的代碼,這樣代碼重用率就...
    機械師的呆子閱讀 796評論 0 0
  • 寫完前一篇文,看到了這一視頻(截圖),只能說:“冥冥之中……” 瞥見,于我一步之遙的貓,時而遙望遠(yuǎn)方,時而與我四目...
    年糕的日常閱讀 241評論 0 0
  • 若你是天,我便是天上云, 默默相守,不離不棄。 若你是地,我便是地上草, 徐徐遍布,靜默相隨。 若你是山,我便是山...
    婧笙瀟閱讀 275評論 0 0

友情鏈接更多精彩內(nèi)容