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')
對(duì)于Python中的函數(shù)參數(shù)睦裳,定義幾個(gè)就傳幾個(gè)參,這個(gè)很好理解撼唾。但是也有一些高級(jí)的或者是簡(jiǎn)化的參數(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)行計(jì)算
# 等價(jià)于 print( powerNum(5,2) )
print( powerNum(2,3) ) # 8
默認(rèn)參數(shù)使用的時(shí)候,一般放在必選參數(shù)后面倒谷,如果有多個(gè)默認(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ù)必須指向不變的對(duì)象,如果是個(gè)可變量的話抖格,每次調(diào)用课舍,默認(rèn)函數(shù)指向的那個(gè)變量的也會(huì)改變
def pushEndToList(li = []):
li.append('END')
print(li)
pushEndToList() # ['END']
pushEndToList() # ['END', 'END']
pushEndToList() # ['END', 'END', 'END']
# 可以看到 默認(rèn)參數(shù)li=[] 指向的不是一個(gè)不變的對(duì)象,
# 調(diào)用函數(shù)的時(shí)候他挎,li指向的對(duì)象的值變了筝尾,那么再次調(diào)用的時(shí)候li的值就已經(jīng)改變了
# 所以,默認(rèn)參數(shù)办桨, 必須要指向一個(gè)不變的對(duì)象(比如None)
- 可變參數(shù)
有時(shí)候我們定義函數(shù)的時(shí)候并不清楚到底需要多少個(gè)參數(shù)筹淫,就可以使用可變參數(shù),使參數(shù)的個(gè)數(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)很清楚了呢撞,另外我們可以看到损姜,這個(gè)可變參數(shù)其實(shí)是一個(gè)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ù)問題,我們來看一個(gè)綜合的例子:
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) {}
# 這個(gè)很好理解殊霞,因?yàn)闆]有傳入kw,默認(rèn)參數(shù)c被賦值了3摧阅,剩下的被當(dāng)成args構(gòu)造出一個(gè)元祖
fn(1,2,3,4,5,name='DeeJay',age=21) # 1 2 3 (4,5) {'name': 'DeeJay', 'age': 21}
# 這次傳入了kw
# 然后來看一個(gè)例子,
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) # 此時(shí)args == (4,5) kw == {'name': 'DeeJay', 'age': 21}
# 這種方法成為拆包
注意最后的fn(1,2,3,*A,**B)
的寫法比规,拆包的作用就是在傳參的時(shí)候若厚,將變量分解作為參數(shù)給函數(shù)。
函數(shù)的return值
在Python中蜒什,函數(shù)如果沒有顯示的寫明return值测秸,那么函數(shù)默認(rèn)return None
此外直接寫return
也等價(jià)于return None
對(duì)于想返回多個(gè)值的函數(shù),可以將多個(gè)值組合為一個(gè)list或者tuple等返回灾常。
def fn():
a = 10
b = 20
c = 30
return a,b,c
res = fn()
print(res) # (10, 20, 30) 是一個(gè)tuple
局部變量和全局變量
Python中的函數(shù)中定義的變量為局部變量:
num = 99
def fn():
num = 100
def printNum():
print(num)
fn()
printNum() # 99
上述例子中霎冯,已經(jīng)在全局環(huán)境中定義了num,所以在fn()中是在拘捕作用域中定義了一個(gè)局部變量num,而不是修改全局中的num,二者僅僅是變量名相同。
如果想要在fn()中修改全局的num钞瀑,那么需要這么寫:
num = 99
def fn():
global num # 表明在內(nèi)部作用域中沒有定義新的局部變量num,這邊的num就是全局變量
num = 100
def printNum():
print(num)
fn()
printNum() # 100 此時(shí)輸出的就是修改過后的全局變量num 為100
上述例子使用global
來聲明是操作一個(gè)全局變量而不是需要重新定義一個(gè)局部變量
但是也有例外肃晚,對(duì)于dict和list,其實(shí)可以不寫global仔戈,程序仍然會(huì)去使用全局變量关串,而不是默認(rèn)先定義一個(gè)局部變量:
# 對(duì)于dict和list,如果是全局變量 其實(shí)可以不用寫global监徘,
# 也會(huì)默認(rèn)使用全局的晋修,而不是先定義一個(gè)
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中的遞歸沒什么特別的地方,寫個(gè)階乘函數(shù)了解一下:
def factorial(n):
if(n == 1):
return 1
return n * factorial(n-1)
res = factorial(4)
print(res)
匿名函數(shù)lambda
- 語(yǔ)法
lambda args: expression
lambda x: x*x
上述例子凰盔, lambda x:
的x
是參數(shù)墓卦,后面的x*x
是作為函數(shù)return的值。
- 用法
使用匿名函數(shù)來進(jìn)行list.sort()
list.sort()接受一個(gè)值為一個(gè)函數(shù)的key户敬,將這個(gè)函數(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ù)其中每個(gè)元素的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ù)的基本用法