函數定義與調用
函數由以下幾個部分組成:
- 函數名
- 函數參數
- 函數體
- 返回值
定義一個函數:
def showMyName(name): #定義函數
print(name)
showMyName("張三") #調用函數
解釋:
- 使用def定義一個函數
- showMyName爲函數名
- name爲形參,"張三"爲實參
- 函數頭以冒號 : 結尾
- 使用縮進區分函數體
- 上例函數沒有返回值。
返回值
什麼是返回值?
如:
a=int(4.5)
解釋:
- int(4.5)就是一個函數,返回值爲4
- 所以a得到的值爲4
應用:
def sum(a,b):
return a+b
print( sum(1,2) ) #輸出3
解釋:
- 通過return來返回結果
- 默認返回None(省略return則返回None)
返回多個值
def func1():
return 1,2,3,4 #將返回一個元組
返回一個函數
- 函數名是一個變量,保存着函數的地址,所以函數可以進行賦值操作
- 所以函數可以作爲返回值
def func1():
print("hello")
def func2():
return func1 #返回一個函數
func2()() #輸出hello
函數參數
形參與實參
函數參數分爲形參和實參
形參是一個變量,而形參是一個值
比如:
def sum(a,b):
return a+b
print( sum(1,2) ) #輸出3
解釋:
- a和b是變量
- 1和2是值
- 1和2按照順序賦值給了a和b(稱爲傳參)
函數作爲參數
- 函數名是一個變量,保存着函數的地址,所以函數可以進行賦值操作
- 所以函數可以作爲實參傳給實參
def func1(func):
func()
def func2():
print("hello")
func1(func2) #輸出:hello
可變對象與不可變對象
傳入可變對象:
def func1(a):
a[0]=100 #原列表將被改變
list1=[1,2,3]
func1(list1) #調用函數
print(list1) #輸出[100, 2, 3]
傳入不可變對象:
def func1(a):
a=100 #實參不會被改變
b=1
func1(b) #調用函數
print(b) #輸出1
解釋:
- 可以看到,形參能夠改變可變對象中的值,但是不能改變不可變對象的值
- 原因是:可變對象傳入的是地址,形參與實參指向的是同一塊內存空間,並且可以直接操作這一塊內存空間。
- 可變對象:字典、列表等類型
- 不可變對象:數字、字符串、元組等類型
必需參數
- 必需參數須以正確的順序傳入函數。調用時的數量也必須和聲明時的一樣
def func1(str):
print("hello")
func1() #無參數,則報錯!!!
關鍵字參數
- 傳入參數時,使用形參名與實參一一對應,這時傳入參數的順序可以不一致。
def func1(a,b,c):
print(a,b,c)
func1(b=2,a=1,c=3) #輸出:1 2 3
比如:
f=open("test.txt","r",encoding="UTF-8") #encoding="UTF-8"就使用了關鍵字參數
默認參數
調用函數時,如果沒有傳遞參數,則會使用默認參數
def func1(name,age=18):
print(name,age)
func1("張三") #使用默認值,輸出:張三 18
func1("張三",20) #覆蓋默認值,輸出:張三 20
注意:
- 擁有默認值的參數必須寫在後面
- 下面的例子會報錯:
def func1(age=18,name): #默認參數寫在了前面,報錯!!!
print(name,age)
不定長參數
加了星號 * 的參數會以元組(tuple)的形式導入
def func1(a,*b):
print(b)
func1(11,22,33) #輸出:(22, 33)
加了兩個星號 ** 的參數會以字典的形式導入
def func1(a,**b):
print(b)
func1(11,b1=22,b2=33) #輸出:{'b1': 22, 'b2': 33}
不定長參數需要寫在形參的最後
如:
def function(name,sex='male',*args,**kwargs): #關鍵參數、默認參數、*args和**kwargs爲不定長參數
print("Hello World!")
function("郭飛","男","a","b","c",愛好="拯救宇宙") #函數調用
各參數的值:
name "郭飛"
sex "男"
args ('a', 'b', 'c')
kwargs {'愛好': '拯救宇宙'}
遞歸函數
函數內部直接或間接調用函數本身,則該函數稱爲遞歸函數。
遞歸函數的特點:
- 直接或間接調用函數本身。
- 有結束邏輯。(即停止調用的邏輯)
一定要有結束的邏輯,不然就會無限循環調用自己。
示例-計算階乘n!
def Leo(n):
sum = 1
if 1 == n: #遞歸終止條件(結束邏輯)
return 1;
sum = n * Leo(n - 1)
return sum #返回階乘的總和
num=input("請輸入一個數字:")
num=int(num)
print( Leo(num) ) #輸出該數的階乘
解釋:
在求X的階乘時,可以利用遞歸的思想:把大問題轉化成小問題,再把小問題轉化成更小的問題,最後得解。
Python內置函數
help(time) #打印關於模塊time的幫助(需要導入模塊)
exit() #退出程序
exit("程序已退出") #退出時輸出提示
exit(1) #退出碼爲1(退出碼爲0的時候是正常)
isinstance([1,2],list) #判斷數據是否爲list
type(name) #查看變量的類型
type(a) is list #a爲列表則返回True
range(100) #0到99
range(1,100) #1到99
range(1,100,2) #1到99裏的奇數(2爲步長)
id(a) #查看變量a的地址
chr(65) #將整數轉爲ASC-II
ord('a') #將一個字符轉換爲它的整數值 (結果爲97)
hex(15) #將一個整數轉換爲一個十六進制字符串 (結果爲0xf)
oct(10) #將一個整數轉換爲一個八進制字符串 (結果爲0o12)
abs(3+4j) #求絕對值 (結果爲5.0)
裝飾器
- 裝飾器用於給函數添加新的功能,比如Debug
- 裝飾器不必修改原函數,就可以給原函數添加新的功能
原函數:
def now():
print("2018-01-01") #只輸出這一行
now()
原函數結果:
2018-01-01
使用裝飾器:
#裝飾器
def log(func):
def wrapper(*args, **kw):
print('call %s():' % func.__name__ ) # 輸出函數名
return func(*args, **kw)
return wrapper
#加裝飾器後
@log #相當於now=log(now)
def now():
print('2018-01-01')
#調用函數
now()
使用裝飾器的結果:
call now():
2018-01-01
解釋:
- 可以看到在原函數上加了@log之後,就添加了函數log的功能。
- 不需要此功能時,刪除@log即可。
- 裝飾器是使用函數嵌套實現的,至於具體邏輯,麻煩自己看看吧~ 文字實在表達不清楚(圖也懶^^),看不懂的直接找我吧~