函數(shù)的返回值
1.什么是返回值
返回值的作用:將函數(shù)里面的數(shù)據(jù)傳遞到函數(shù)外面
初學(xué)者怎么確定需不需要返回值:看函數(shù)功能會不會產(chǎn)生新的數(shù)據(jù)
怎么確定函數(shù)返回值:函數(shù)聲明的時候return后面的值就是函數(shù)的返回值
如果沒有return則返回None
a.return: 關(guān)鍵字:只能出現(xiàn)在函數(shù)體中
作用:確定函數(shù)返回值;結(jié)束函數(shù)(執(zhí)行函數(shù)體的時候如果遇到return,
函數(shù)直接結(jié)束,同時返回后面的值)怎么獲取函數(shù)的返回值:函數(shù)調(diào)用表達式就是返回值
函數(shù)調(diào)用表達式:函數(shù)調(diào)用語句;普通數(shù)據(jù)能做的事情函數(shù)調(diào)用表達式都可以
# 1.確定確定返回值
def sum1(num1, num2):
return num1 + num2
# 2.獲取函數(shù)返回值
def fun2(num):
return num*2
# a.函數(shù)調(diào)用表達式可以給變量賦值
a = fun2(2)
print(a)
print(fun2(2)+2)
list1 = [fun2(2), 10]
print(list1)
def func3():
return []
list2 = func3()
list2.append(100)
print(list2)
2.函數(shù)調(diào)用過程
1)執(zhí)行過程
a.回到函數(shù)聲明的位置
b.傳參 - 保證每個參數(shù)都有值
c.執(zhí)行函數(shù)體
d.執(zhí)行完函數(shù)體確定返回值:看執(zhí)行完函數(shù)體的時候有沒有遇到return,
如果遇到return后面就是返回值,沒有就是None
e.回到函數(shù)調(diào)用的位置(這個時候函數(shù)調(diào)用表達式的值才是函數(shù)返回值)
2)內(nèi)存變化:函數(shù)的調(diào)用過程是一個壓棧的過程
調(diào)用函數(shù)的時候系統(tǒng)會自動在棧區(qū)間為這個函數(shù)開辟一個專用的內(nèi)存區(qū)域,
專門用來保存這個函數(shù)中聲明的變量和產(chǎn)生的數(shù)據(jù)(形參也是聲明在函數(shù)的變量)
當函數(shù)調(diào)用結(jié)束的時候,這個內(nèi)存區(qū)域會自動銷毀(銷毀將返回值扔出來)
def func4(n):
print(n)
return n*2
a = func4(3)
print(a)
變量的作用域
1.變量的作用域 - 變量可以使用的范圍
2.全局變量和局部變量
1)全局變量
沒有聲明在函數(shù)中或者類中的變量都是全局變量
全局變量從聲明開始到文件結(jié)束任何地方都可以使用
2)局部變量
聲明在函數(shù)中的變量就是局部變量
從聲明開始到函數(shù)結(jié)束(形參是聲明在函數(shù)中的變量)
# a是全局變量
a = 10
# b也是全局變量
for b in range(4):
# c也是全局變量
c = 100
pass
print(b)
def fun1():
print('函數(shù)中:', a, b, c)
fun1()
# aa和bb都是局部變量
def func2(aa):
bb = 200
print('外函數(shù)', aa, bb)
def func3():
cc = 300
print('內(nèi)函數(shù)', aa, bb)
func3()
# print('外函數(shù)',cc) NameError: name 'cc' is not defined
func2(100)
# print(aa) #NameError: name 'aa' is not defined
3.global和nonlocal
global和nonlocal這兩個關(guān)鍵字只能在函數(shù)體中使用
1)global
在函數(shù)中給變量賦值前加:global 變量名
作用:在函數(shù)中聲明全局變量
如果外部沒有事先聲明,可以直接在函數(shù)內(nèi)部用global 變量聲明
函數(shù)銷毀后外部依然可用
2)nonlocal
使用方法:在函數(shù)中給變量賦值前加:nonlocal 變量名
作用:在內(nèi)函數(shù)中修改局部變量的值,就如同函數(shù)作用域中的global
# 全局變量a1
a1 = 100
b1 = 100
def func4():
# 聲明一個局部變量a1
a1 = 200
# 聲明b1是全局變量
global b1
b1 = 300 # 修改全局變量的值
# 使用的局部變量a1,使用全局變量b1
global c1 # 外部沒有聲明依然可以直接聲明
c1 = 500
print('函數(shù)內(nèi)', a1, b1, c1)
func4()
# 使用的是全局變量a1
print('函數(shù)外', a1, b1, c1)
print('===============nonlocal================')
def func5():
a2 = 100
b1 = 100
def func6():
a2 = 200
nonlocal b1
# nonlocal c1 外函數(shù)沒有不能直接聲明,跟global不一樣
# c1 = 100 只能修改,不能建立
b1 = 200
print('函數(shù)的函數(shù)中:', a2, b1)
func6()
print('函數(shù)中', a2, b1)
func5()
匿名函數(shù)
1.什么是匿名函數(shù) - 沒有名字的函數(shù)
"""
匿名函數(shù)還是函數(shù),普通函數(shù)中除了聲明的語法以外其他語法基本都適用于匿名函數(shù)
1)聲明匿名函數(shù)
lambda 參數(shù)列表:返回值
2)說明:
lambda - 關(guān)鍵字,固定寫法
相當于:
def (參數(shù)列表):
return 返回值
參數(shù)列表 - 形參:參數(shù)名1,參數(shù)名2,...
: - 固定寫法
返回值 - 相當于普通函數(shù)中函數(shù)體的return語句
"""
# 用匿名函數(shù)實現(xiàn)求兩個數(shù)的和
func1 = lambda x, y: x + y
# 匿名函數(shù)的調(diào)用和普通函數(shù)沒有區(qū)別
print(func1(10, 20))
print(func1(x=3, y=5))
func2 = lambda a=1, b=2, c=3: print(a, b, c)
func2()
func2(b=10)
func3 = lambda *nums: sum(nums)
print(func3(10, 20, 30))
print(func3(1, 2, 3, 4))
# 注意:不支持類型說明
# 練習(xí):寫一個匿名函數(shù)判斷指定的年是否是閏年
r_year = lambda x: (x % 4 == 0 and x % 100 != 0) or x % 400 == 0
print(r_year(2002))
遞歸函數(shù)
1.什么是遞歸函數(shù)
聲明函數(shù)的時候調(diào)用函數(shù)本身,這樣的函數(shù)就是遞歸函數(shù)(自己調(diào)自己)
遞歸可以實現(xiàn)循環(huán)效果,原則上除了死循環(huán),其他的循環(huán)遞歸都可以實現(xiàn)
2.遞歸怎么用
使用遞歸的套路:
a.設(shè)置臨界值 - 循環(huán)結(jié)束的條件(保證函數(shù)結(jié)束)
b.找關(guān)系 - 找f(n)和f(n-1)的關(guān)系
c.假設(shè)函數(shù)功能已經(jīng)實現(xiàn),通過f(n-1)去實現(xiàn)f(n)的功能
# 寫一個遞歸函數(shù),計算1+2+3....n
def sum1(n):
# 找臨界值
if n == 1:
return 1
# 找關(guān)系
"""
f(n) -> 1+2+3.....n-1+n
f(n-1) -> 1+2+3...n-1
f(n) = f(n-1) + n
"""
# 用f(n-1)實現(xiàn)f(n)的功能
return sum1(n-1) + n
print(sum1(10))
# 寫一個遞歸函數(shù),求斐波那契數(shù)列的第n個數(shù)
# 1,1,2,3,5,8,13.....
def series(n):
if n == 1 or n == 2:
return 1
return series(n-1)+series(n-2)
print(series(5))
# 練習(xí):
"""
n = 4
*
**
***
****
"""
def f(n):
if n == 1:
print('*')
return
f(n-1)
print('*'*n)
f(5)