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ù)的基本用法