第五章 Python 函數
第1章 為什麽要使用函數
#1、代碼的組織結構不清晰,可讀性差
#2、遇到重復的功能只能重復編寫實現代碼,代碼冗余
#3、功能需要擴展時,需要找出所有實現該功能的地方修改之,無法統一管理且維護難度極大
第2章 函數是什麽
定義:函數是指將一組語句的集合通過一個名字(函數名)封裝起來,要執行這個函數,只需要調用函數名即可。
特性:
1、減少重復代碼
2、使程序變的可擴展
3、使程序變得易維護
函數的使用必須遵循:先定義,後調用
2.1 函數的分類
1、 內置函數:python解釋器自帶的函數,python解釋器啟動就會定義好這些函數
如len(),sum(),max(),min()
2、自定義函數:開發人員根據需求,定制好自己的函數來實現某種功能,在遇到應用場景時,調用自定義函數即可。
2.2 定義函數語法
def 函數名(參數1,參數2,...)
""" 註釋 """
函數體
return 返回值
def = define(定義)
#函數名要能反映其意義
2.3 函數的定義與調用
### 定義一個函數,並且調用
def hello():
print(‘hello word‘)
hello()
>>> hello word
### 函數與變量一樣,函數的內容也會占用內存空間
### 打印函數名會返回函數所占的內存空間
def hello():
print(‘hello word‘)
print(hello)
<function hello at 0x000000DD707F3E18>
2.4 函數的使用規則:先定義 再調用
函數即“變量”,“變量”必須先定義後引用。未定義而直接引用函數,就相當於在引用一個不存在的變量名
函數在定義階段,只檢測語法,不執行代碼
def foo():
print(‘from foo‘)
bar() #報錯 在定義的時候就已經報語法錯誤了
foo()
def bar():
print(‘from bar‘)
def foo():
print(‘from foo‘)
bar()
foo() #正常
### 不會報錯,因為在定義階段沒有出現語法錯誤
def foo():
print(‘from foo‘)
bar()
def bar():
print(‘from bar‘)
foo()
#結論:函數的使用,必須遵循原則:先定義,後調用
#我們在使用函數時,一定要明確地區分定義階段和調用階段
#定義階段
def foo():
print(‘from foo‘)
bar()
def bar():
print(‘from bar‘)
#調用階段
foo()
函數在定義階段都幹了哪些事?
只檢測語法,不執行代碼
也就說,語法錯誤在函數定義階段就會檢測出來,而代碼的邏輯錯誤只有在執行時才會知道
第3章 定義參數的三種形式
#1、無參:應用場景僅僅只是執行一些操作,比如與用戶交互,打印
#2、有參:需要根據外部傳進來的參數,才能執行相應的邏輯,比如統計長度,求最大值最小值
#3、空函數:設計代碼結構
3.1 無參
def login():
while
True:
user_name=input(‘user_name>>>: ‘).strip()
if
not user_name:continue
user_pass=input(‘user_pass>>>:
‘).strip()
if user_name
== ‘leo‘ and user_pass
== ‘123‘:
print(‘登錄成功‘)
else:
print(‘登錄失敗‘)
login()
### 這是一個無參函數,雖然滿足邏輯,但是用戶名和密碼都寫死在函數體力,無法靈活使用。
3.2 傳參
def main():
while
True:
name=input(‘name>>> ‘).strip()
if
not name:continue
password=input(‘password>>>:
‘).strip()
if
not password:continue
res=arth(name,password)
if res:
print(‘登錄成功‘)
else:
print(‘登錄失敗‘)
def arth(user,password):
if user
== ‘leo‘ and password
== ‘123‘:
return
True
else:
return
False
main()
3.3 空函數
def auth(user,password):
‘‘‘
auth function
:param user: 用戶名
:param password: 密碼
:return: 認證結果
‘‘‘
pass
def get(filename):
‘‘‘
:param filename:
:return:
‘‘‘
pass
def put(filename):
‘‘‘
:param filename:
:return:
‘‘‘
def ls(dirname):
‘‘‘
:param dirname:
:return:
‘‘‘
pass
#程序的體系結構立見
第4章 調用函數
4.1 調用函數
#1 調用函數:函數名(),
#需要註意:先通過名字找到函數的內存地址,然後加括號調用
4.2 函數的返回值
#註意的第一點:
#在調用函數的過程中,一旦執行到return,就會立刻終止函數,並且把return後的結果當做本次調用的返回值返回
#函數體內可以有多個return,但是只能執行一次
def foo():
print(‘111‘)
return 1
print(‘2222‘)
return 2
print(‘3333‘)
return 3
res=foo()
print(‘函數調用完畢‘,res)
#註意的第二點:
#返回的值,可以是任意類型
#註意的第三點:
#沒有return:默認返回None
#可以返回一個值===>值
#可以用逗號分隔,返回多個值===>tuple
def foo():
return None
res=foo()
print(‘函數調用完畢‘,res,type(res))
>>> 函數調用完畢 None <class ‘NoneType‘>
4.3 調用函數的三種形式
1 語句形式:foo()
2 表達式形式:3*len(‘hello‘)
3 當中另外一個函數的參數:range(len(‘hello‘))
語句模式:
def foo():
print(‘from foo‘)
return 123
foo()
>>> from foo
def foo():
print(‘from foo‘)
return 123
res=foo()
print(res)
>>> 123
res=foo()*10
print(res)
>>> 1230
第5章 函數的參數
5.1 形參與實參
#形參:在函數定義階段,括號內定義的參數的稱為形參,就相當於變量名
#實參:在函數調用階段,括號內定義的參數的稱為實參,就相當於變量值
#在調用階段,實參的值會綁定給形參,在調用結束後,解除綁定
5.2 參數的分類
5.2.1 位置參數
1、位置參數:按照從左到右的順序定義的參數
位置形參:必須被傳值的參數
位置實參:按照位置給形參傳值,從左到右
def foo(x,y): #x=1,y=2 #形參
print(x,y)
foo(1,2) #實參
5.2.2 關鍵字參數
2、關鍵字參數:按照key=value的形式定義的實參
無需按照位置為形參傳值
註意的問題:
1. 關鍵字實參必須在位置實參後面
2. 對同一個形參不能重復傳值
def foo(x,y):
print(x,y)
foo(1,y=20)
5.2.3 默認參數
三:默認參數:在定義函數階段,已經為形參賦值了,在定義階段已經賦值,意味著在調用階段
可以不傳值
註意的問題:
1 默認參數的值,只在定義時賦值一次
2 位置形參應該在默認參數的前面
3 默認參數的值應該是不可變類型
def foo(x,y=10):
print(x,y)
foo(x=1)
>>> 1 10
def foo(x,y,z=10):
print(x,y,z)
foo(x=1,y=2)
>>> 1 2 10
位置參數 > 關鍵字參數 > 默認參數
### 如果實參在調用階段傳參,那麽將使用傳參而不使用默認參數,但是不建議這麽用
def register(name,age,sex=‘male‘):
print(name,age,sex)
register(‘egon‘,18)
register(‘wsb‘,18)
register(‘alex‘,38,‘xxxxxx‘)
>>> egon 18 male
>>> wsb 18 male
>>> alex 38 xxxxxx
### 只在定義的時候賦值一次,賦值完成後,再賦值將不改變默認參數
x=‘123‘
x=‘456‘
def register(name,age,sex=x):
print(name,age,sex)
x=‘female‘
register(‘alex‘,18)
>>> alex 18 456
5.2.4 可變長參數(非固定參數)
四:可變長參數
實參可變長度指的是:實參值的個數是不固定
而實參的定義形式無非兩種:1、位置實參,2、關鍵字實參
針對這兩種形式的實參個數不固定,相應的,形參也要有兩種解決方案
分別是*args,**kwargs
def func(x,y,z,*args): #args=(4,5,6)
print(x,y,z)
print(args)
func(1,2,3)
>>> 1 2 3
>>> ()
### 情景是加入新參數的時候使用:
def str_register(name,age,country,course,*args):
print(‘------註冊學員信息------‘)
print(‘姓名: %s‘ %(name))
print(‘年齡: %s‘ %(age))
print(‘國籍: %s‘ %(country))
print(‘科目: %s‘ %(course))
print(‘other args‘,args)
str_register(‘leo‘,28,‘CN‘,‘Python‘)
------註冊學員信息------
姓名: leo
年齡: 28
國籍: CN
科目: Python
other args ()
### 如果我什麽都不傳給 其他參數的話 並不會報錯,而且會返回來一個空元組
### 如果傳值 將會被放到元組中,可從中拿出來
def str_register(name,age,country,course,*args):
print(‘------註冊學員信息------‘)
print(‘姓名: %s‘ %(name))
print(‘年齡: %s‘ %(age))
print(‘國籍: %s‘ %(country))
print(‘科目: %s‘ %(course))
print(‘other args‘,args)
str_register(‘leo‘,28,‘CN‘,‘Python‘,‘stu001‘,10000)
------註冊學員信息------
姓名: leo
年齡: 28
國籍: CN
科目: Python
other args (‘stu001‘, 10000)
### 將溢出的參數 放入字典中
### 如果在傳參時沒有指定名字,那麽他就是*args,非固定參數的元組模式
### 如果指定名字了,那麽他就是**kwargs,非固定參數的字典模式
def str_register(name,age,country,course,*args,**kwargs):
print(‘------註冊學員信息------‘)
print(‘姓名: %s‘ %(name))
print(‘年齡: %s‘ %(age))
print(‘國籍: %s‘ %(country))
print(‘科目: %s‘ %(course))
print(‘other args‘,args)
print(‘other args‘,kwargs)
str_register(‘leo‘,28,‘CN‘,‘Python‘,10000,stuid=‘stu001‘)
------註冊學員信息------
姓名: leo
年齡: 28
國籍: CN
科目: Python
other args (10000,)
other args {‘stuid‘: ‘stu001‘}
比如將來要用到這個參數了,就可以直接用字典方式取值:
def str_register(name,age,country,course,*args,**kwargs):
print(‘------註冊學員信息------‘)
print(‘姓名: %s‘ %(name))
print(‘年齡: %s‘ %(age))
print(‘國籍: %s‘ %(country))
print(‘科目: %s‘ %(course))
print(‘other args‘,args)
print(‘other args‘,kwargs)
print(‘學號:%s‘ %(kwargs[‘stuid‘]))
str_register(‘leo‘,28,‘CN‘,‘Python‘,10000,stuid=‘stu001‘)
------註冊學員信息------
姓名: leo
年齡: 28
國籍: CN
科目: Python
other args (10000,)
other args {‘stuid‘: ‘stu001‘}
學號:stu001
def foo(x, y, z):
print(x,
y, z)
foo(**{‘z‘: 1,
‘x‘: 2, ‘y‘: 3})
5.2.5 命名關鍵字函數
#五:命名關鍵字參數(了解):
# 形參中,在*後定義的參數稱之為命名關鍵字參數,
# 它的特性是;傳值時,必須按照關鍵字實參的形式傳值
def foo(x,y=20,*args,a=1,b):
print(x,y,a,b)
# foo(10,b=3)
foo(10,22,33,44,a=2,b=3)
>>> 10 22 2 3
# 位置參數,默認參數,*args,命名關鍵字參數,**kwargs
第五章 Python 函數