1纱控,函數的使用
"""
1 什么是函數
函數是盛放功能的容器辆毡,說白了,把實現某一功能的一組代碼
扔到一個函數中甜害,就做成了一個小工具舶掖,該工具可以重復使用
實現某一功能的工具-》函數
事先準備工具的過程-》函數的定義
遇到應用場景拿來就用-》函數的調用
2 為何要用函數
沒有用函數前,程序存在的問題有
1尔店、代碼冗余眨攘、程序的組織結構不清晰、可讀性差
2嚣州、可擴展性差
3 如何用函數
原則:先定義鲫售、后調用
"""
一 定義函數的語法
def 函數名(參數1,參數2,參數3,...):
"""函數注釋"""
代碼1
代碼2
代碼3
return 返回值
def haha():
print('*' * 10)
print('hello world'.center(10,' '))
print('*' * 10)
# 打印haha這個函數的內存地址
print(haha)
# <function haha at 0x1009b61f0>
# 調用函數haha
haha()
# **********
# hello world
# **********
PS:
只有函數才能調用!8秒取情竹!
# 會報錯
x=10
x()
# x()
# TypeError: 'int' object is not callable
2,定義與調用之間的關系
def say():
print('*' * 20)
print('hello world'.center(20, ' '))
print('*' * 20
# 以上少了個括號匀哄,語法錯誤會報錯
# SyntaxError: unexpected EOF while parsing
# 邏輯錯誤不會報錯秦效,age沒有定義雏蛮,加上引號才不會報錯
def say():
print('*' * 20)
print('hello world'.center(20, ' '))
print('*' * 20)
print(age)
# 執(zhí)行的時候會報錯
say()
# NameError: name 'age' is not defined
#例1:
def hh():
aa()
print(11)
print(hh)
# <function hh at 0x1048b21f0>
hh()
#NameError: name 'aa' is not defined
總結:
# 以上aa()沒有定義,打印hh這個函數額內存地址時候不會報錯阱州;只有在調用hh的時候才會報錯
#例2
def hh():
aa()
print('x')
hh()
# 會報錯挑秉,因為x沒有定義,NameError: name 'aa' is not defined
#例3
def hh():
print('x')
x=3
hh()
#x
# 以上雖然 x=3沒有在函數前定義苔货,但是調用函數前是有x的定義的犀概,所以不會報錯
3,定義的3種格式
#示例:兩值比較蒲赂,獲取大的數字
# 空函數:為了先定義好函數的模版
# pass充當占位符阱冶,程序設計的開始沒想好具體功能,pass顯得結構清晰
def auth_user():
'''注冊功能'''
pass
# 無參函數
def foo():
x=10
y=3
if x>y:
print(x)
else:
print(y)
foo()
# 10
# 有參函數
def foo1(x,y):
if x > y:
print(x)
else:
print(y)
foo1(2,4)
# 4
或可以修改無參函數如下
def foo2():
x=input('>>>>>')
y=input('>>>>>')
x=int(x)
y=int(y)
if x>y:
print(x)
else:
print(y)
foo2()
# >>>>>9
# >>>>>8
# 9
例(以下兩個代碼一樣的效果):
def say(char,size,msg): # say -> 函數的內存地址
print(f'{char}'*size)
print(f'{msg}'.center(size,' '))
print(f'{char}'*size)
def say1(char,size,msg): # say -> 函數的內存地址
print(char*size)
print(msg.center(size,' '))
print(char*size)
say1('#',40,'hahaha')
# ########################################
# hahaha
# ########################################
4滥嘴,函數的返回值
# return的返回值: 函數內可以有多個return,但是只要執(zhí)行1次,整個函數就立即終止
# return可以返回任意類型的值,并且可以返回多個
# return的用途
#例1
def max(x,y):
if x > y:
return x
else:
return y
data=max(3,5)
print(data * 3)
# 15
#例2
def foo(x,y,z):
return x,y,z
res=foo(1,2,3)
print(res)
# (1, 2, 3)
#return跟列表木蹬,也是返回元祖類型
def foo(x,y,z):
return x,y,z
res=foo(1,2,[1,5])
print(res)
(1, 2, [1, 5])
例3:
1)
def foo1():
user=input('your name:')
password=input('your password:')
return (user,password)
# 以上沒有返回值
res=foo1()
print(res)
# your name:zx
# your password:123
# ('zx', '123')
2)
# 不加return值或者return空返回值為None
def foo1():
user=input('your name:')
password=input('your password:')
#return (user,password)
res=foo1()
print(res)
# your name:zx
# your password:123
# None
5,調用函數的3種方式
# 比較數字大寫若皱,顯示數字較大的那個
def max2(x, y):
if x > y:
return x
else:
return y
#1, 語句形式(返回的是空)
max2(10, 20)
#2, 表達式形式(賦值镊叁,輸出)
res = max2(10,20)
print(res)
# 20
res = max2(10,20) * 12
print(res)
# 240
#3, 可以把函數調用傳給另外一個函數
res = max2(max2(10,20),30)
print(res)
# 30
6,函數的參數格式
1) 行參和實參
形參: 在函數定義階段括號內定義的參數(變量名),稱之為形式參數,簡稱形參
實參: 在函數調用階段括號內傳入的值(變量值),稱之為實際參數,簡稱實參
2)行參
# 行參:
1)位置行參
2)默認行參
位置行參:在函數定義階段按照位置定義的形參
特點:必須被傳值
# 正確示例:
def foo(x,y):
print(x)
print(y)
foo(1,2)
# 1
# 2
# 錯誤示例:
def foo(x,y):
print(x)
print(y)
# 以下都會報錯
foo(1,)
foo(,4)
foo()
默認行參:函數定義階段就已經為某個形參賦值了
特點:可以不用為其傳值
正確示例:
def foo(x,y=666):
print(x)
print(y)
foo(3)
# 3
# 666
foo(2,9)
# 2
# 9
注意:
1 位置形參必須在前
def foo(y=666,x):
pass
2 默認形參的值通常應該為不可變類型
例:
def reg(name,age,gender='male'):
print(name,age,gender)
reg('zx',13,'female')
# zx 13 female
# 不賦值即默認值
reg('egon',21)
# egon 21 male
3) 實參
# 位置參數
def register(name,age,sex):
print('Name:%s Age:%s Sex:%s' %(name,age,sex))
register('zx',3,'male') # 必須要傳值
# Name:zx Age:3 Sex:male
# 定義關鍵字參數:在函數調用階段按照key=value的形式傳值
def register(name,age,sex):
return
register(name='bb',sex=3,age=9)
# Name:bb Age:9 Sex:3
# 混合使用
register('lili',sex='male',age=18)
注意:
def register(name,age,sex):
print('Name:%s Age:%s Sex:%s' %(name,age,sex))
register(name='lili',18,sex='male') # 會報錯走触,位置實參必須在前面
register('lili',18,sex='male',name='pp') # 會報錯晦譬,不能多賦值/不能為用一個行參賦值
PS:
默認參數必須在位置參數之后
默認參數的值僅在函數定義階段被賦值一次
# 定義階段arg已經賦值于x
x=1
def foo(arg=x):
print(arg)
x=4 # 這里的x修改與args無關
foo()
# 1
默認參數的值通常應設為不可變類型
def foo(n, arg=[]):
arg.append(n)
return arg
res=foo(1)
print(res)
# [1]
res1=foo(2)
print(res1)
# [1, 2]
res2=foo(3)
print(res2)
# [1, 2, 3]
# 每次調用是在上一次的基礎上向同一列表增加值
def foo(n, arg=None):
if arg is None:
arg = []
arg.append(n)
return arg
res=foo(1)
print(res)
# [1]
res1=foo(2)
print(res1)
# [2]
7,可變長參數
1)可變長度的位置參數
args 在行參名前面加上*互广,在調用函數的時候敛腌,
溢出的位置實參都會被接收,以元祖的形式賦值給該行參
# 例1
def foo(x,y,*args):
print(x)
print(y)
print(args)
foo(1,2,3,4,5)
# 1
# 2
# (3, 4, 5)
# 例2(列表類型)
def foo(x,y,*args):
print(x)
print(y)
print(args)
# 先定義好一個列表
L=[4,5,6]
# 實參調用列表惫皱,傳值給args
foo(1,2,*L)
# 1
# 2
# (4, 5, 6)
# 注意以上實參調用要加上*像樊,不然會被會被默認為一個普通的位置參數
foo(1,2,L)
# 1
# 2
# ([4, 5, 6],)
# 例3: 多值求和
def add(*args):
res=0
for i in args:
res+=i
return res
res1=add(1,2,3)
print(res1)
# 6
2)可變長度的關鍵字參數
# 形參名前加**,在調用函數時,溢出的關鍵字參數旅敷,都會被接收生棍,以字典的形式保存下來賦值給該形參
# 例1
def foo(x,**kwargs):
print(x)
print(kwargs)
foo(x=1,y=2,z=3)
# 1
# {'y': 2, 'z': 3}
# 例2:字典傳值給參數
def foo(x,**kwargs):
print(x)
print(kwargs)
# 事先定義好一個字典
L={'a':1,'b':2,'c':3}
# 字典傳入參數調用
foo(999,**L)
# 999
# {'a': 1, 'b': 2, 'c': 3}
#PS:如果不加上**,會報錯媳谁,因為foo只需要一個位置參數涂滴,卻傳入了三個
foo(999,L)
# TypeError: foo() takes 1 positional argument but 2 were give
# 例3: 行參為默認/位置,實參也可以**的形式
def foo(x,y,z=3):
print(x)
print(y)
print(z)
foo(**{'x':1,'y':2})
# 1
# 2
# 3
3)命名關鍵字參數
# 在python3中晴音,定義行參數時柔纵,加上*作為一個分隔符,*之后的額參數必須用key value的方式傳入值(必須要傳值)
def register(name,age,*,sex,height):
print(name,age,sex,height)
# 正確示例
register('lili',18,sex='male',height='1.8m')
# lili 18 male 1.8m
register(name='lili',age=18,sex='male',height='1.8m')
# 錯誤示例(會報錯)
#register('lili',13,'female','1.2m')
# 如果形參中已經有一個args了锤躁,命名關鍵字參數就不再需要一個單獨的*作為分隔符號了
def register(name,age,*args,sex,gender):
print('Name:%s,Age:%s,Args:%s,Sex:%s,Gender:%s' %(name,age,args,sex,gender))
register('pp',12,1,2,3,4,sex='female',gender=12)
# Name:pp,Age:12,Args:(1, 2, 3, 4),Sex:female,Gender:12
# 錯誤示例:
register('pp',12,1,2,3,4,'female',12)
# TypeError: register() missing 2 required keyword-only arguments: 'sex' and 'gender
只要在*后面的參數都是命名關鍵字參數J琢俊!!<釉怠Q夹稹!
4)組合使用
# 可變參數*args與關鍵字參數kwargs通常是組合在一起使用的拣宏,如果一個函數的形參為*args與kwargs沈贝,那么代表該函數可以接收任何形式、任意長度的參數
def func(x,y,z):
print(x,y,z)
def wrapper(*args,**kwargs):
func(*args,**kwargs)
# 在為函數wrapper傳參時勋乾,其實遵循的是函數func的參數規(guī)則
wrapper(1,2,3)
# 1 2 3
總結:
!!!!!!!!
**kwargs中的args和kwargs被替換成其他名字并無語法錯誤宋下,
但使用args、kwargs是約定俗成的辑莫。
*在形參中: 會溢出的位置實參存成元組然后賦值給緊跟其后的形參名
*在實參參中: *會將后面的值打散成位置實參
**在形參中:會溢出的關鍵字實參存成字典然后賦值給緊跟其后的形參名
**在實參中:*會將后面的字典打散成關鍵字實參
!!!!!!