一、函數(shù)變量
二、匿名函數(shù)
三、遞歸函數(shù)
四、函數(shù)的調(diào)用過(guò)程
五、使用函數(shù)模塊
一、函數(shù)變量
1、函數(shù)名就是函數(shù)類(lèi)型變量(類(lèi)別名:function),存的是函數(shù)的入口地址
def func1():
print('aaa')
print(type(func1)) # <class 'function'>
num = 10
print(type(num)) # <class 'int'>
2、可以使用一個(gè)變量給另一個(gè)變量賦值
# a = func1() # 這樣賦值,是將函數(shù)func1的返回值賦給a
a = func1 # 將函數(shù)變量func1賦給a, a就會(huì)變成一個(gè)函數(shù)
a() # 現(xiàn)在就可以用函數(shù)變量a,去調(diào)用函數(shù)func1
def func2(num):
return num*2
b = func2 #這里的b和func2具有相同的功能
print(func2(10))
print(b(20))
3、函數(shù)變量作為函數(shù)的參數(shù)
def calculate(num1, num2, fn):
# num1 = 10 num2 = 20 fn = func_add
# 如果num1不是int或者float數(shù)據(jù)
if not (isinstance(num1, int) or isinstance(num1, float)):
print('num1不是數(shù)字')
return None # 在這兒讓函數(shù)直接結(jié)束
if not (isinstance(num2, int) or isinstance(num2, float)):
print('num2不是數(shù)字')
return None # 在這兒讓函數(shù)直接結(jié)束
return fn(num1, num2) # return func_add(10, 20) return 30
def func_add(m, n):
# m = 10 n = 20
return m + n # return 30
def func_sub(m, n):
return m - n
result = calculate(10, 20, func_add)
print(result)
4、函數(shù)作為返回值
寫(xiě)一個(gè)函數(shù),func3('+') -> 返回求和的功能;func3('*')-> 返回求乘積的功能
def func3(char):
if char == '+':
# python中,是可以在函數(shù)中聲明函數(shù)
def fn(*nums):
sum1 = 0
for x in nums:
sum1 += x
return sum1
return fn
if char == '*':
def fn(*nums):
sum1 = 1
for x in nums:
sum1 *= x
return sum1
return fn
result = func3('+') # reslut是一個(gè)求和功能的函數(shù)的函數(shù)變量
print('aaa', result(1, 2, 3, 4))
result2 = func3('*')(10, 20)
print(result2)
aaa 10
200
列表作為返回(對(duì)象變量作為返回值)
def func4():
list1 = [1, 2, 3]
return list1
result = func4()
print(result)
print(func4()[0])
[1, 2, 3]
1
二、匿名函數(shù)
python中使用lambda關(guān)鍵字來(lái)聲明一個(gè)匿名函數(shù)
格式: lambda 參數(shù)列表:返回值
其中參數(shù)列表中有多個(gè)參數(shù)時(shí),用逗號(hào)隔開(kāi)
使用函數(shù)實(shí)現(xiàn)求兩個(gè)數(shù)的和
def func1(num1, num2):
return num1 + num2
print(func1(10, 20))
30
練習(xí):使用匿名函數(shù)求指定列表中,指定的兩個(gè)下標(biāo)對(duì)應(yīng)的元素的和
func3 = lambda list1, index1, index2: list1[index1]+list1[index2]
print(func3([11, 4, 8, 9, 20], 0, 2))
19
三、遞歸函數(shù)
1、遞歸函數(shù):
1.在函數(shù)聲明時(shí)調(diào)用函數(shù)本身
2.遞歸作用:理論上循環(huán)能夠做到的事情遞歸都可以做(但實(shí)際除非是非用不可的情況,一般不用遞歸)
3.步驟:
遞歸函數(shù):f(n)
a. 確定臨界值(結(jié)束函數(shù)的時(shí)刻)
b. 假設(shè)函數(shù)的功能已經(jīng)實(shí)現(xiàn),然后找到f(n)和f(n-1)關(guān)系
c. 使用f(n-1)與f(n)的關(guān)系去實(shí)現(xiàn)f(n)的功能
計(jì)算1+2+3+4+...+n
方法1:使用循環(huán)
def func1(n):
sum1 = 0
for x in range(1, n+1):
sum1 += x
return sum1
print(func1(100))
5050
方法2:使用遞歸函數(shù)
def func2(n):
# 1.確定臨界值
if n == 1:
return 1
# 2.假設(shè)func2功能實(shí)現(xiàn)了,找func2(n-1), func2(n)的關(guān)系
# func2(n-1) = 1+2+3+...+n-1
# func2(n) = 1+2+3+...+n-1+n = func2(n-1)+n
# 3.通過(guò)func2(n-1)去實(shí)現(xiàn)func2(n)的功能
return func2(n-1)+n
print(func2(100))
5050
例題:
n = 5
***** 0 5*
**** 1 4*
*** 2 3*
** 3 2*
* 4 1*
def print_star2(n):
if n == 1:
print('*')
return None
print('*'*n)
print_star2(n-1)
print_star2(5)
*****
****
***
**
*
四、函數(shù)的調(diào)用過(guò)程
函數(shù)調(diào)用的過(guò)程是一個(gè)壓棧的過(guò)程:
a.調(diào)用函數(shù)的時(shí)候,首先會(huì)在棧中開(kāi)辟一塊內(nèi)存空間,用來(lái)保存函數(shù)調(diào)用過(guò)程中產(chǎn)生的數(shù)據(jù)(包括函數(shù)的參數(shù)和在函數(shù)中聲明的變量)
b.當(dāng)函數(shù)執(zhí)行完成后,被調(diào)用函數(shù)對(duì)應(yīng)的內(nèi)存空間會(huì)被回收(釋放)
棧:是內(nèi)存中的一塊特殊的區(qū)域。數(shù)字和字符串的值是存在棧里面的
堆:對(duì)象是存在堆里面的
總結(jié): 遞歸要慎用!(能用循環(huán)做的,就不要用遞歸。遞歸消耗內(nèi)存也消耗CPU資源)
五、使用模塊管理函數(shù)
通過(guò)import關(guān)鍵字導(dǎo)入模塊,然后通過(guò) 模塊名.函數(shù) 的方法去使用模塊中的函數(shù)
注意: 當(dāng)我們導(dǎo)入其他的模塊的時(shí)候,會(huì)將其他模塊中的所有的內(nèi)容都會(huì)導(dǎo)入到當(dāng)前文件中通過(guò)from-import直接導(dǎo)入指定的函數(shù)。導(dǎo)入后就可以直接調(diào)用函數(shù)
格式: from 模塊名 import 函數(shù)名1, 函數(shù)名2通過(guò) as關(guān)鍵字給導(dǎo)入模塊或者函數(shù)重命名
關(guān)于name屬性:
name是每個(gè)模塊都有的屬性,作用是用來(lái)存儲(chǔ)模塊的名字。
當(dāng)模塊不是正在執(zhí)行的模塊,name屬性的值是模塊對(duì)應(yīng)的文件的文件名;
當(dāng)模塊正在執(zhí)行的時(shí)候,name的值就是一個(gè)固定值'main'