函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段,函数能提高应用的模块性,和代码的重复利用率。
创建函数
def FunctionName(parameter):
['''comments''']
[function body]
- FunctionName:函数名称
- parameter:可选参数,用于指定向函数中传递的参数。如果有多个参数,各参数间使用逗号","分隔。如果不指定,则表示该函数没有参数,在调用时也不指定参数。
- comments:可选参数,函数的注释。
- function body:函数的代码块。
示例代码:
def funname(number):
"""传入一个参数返回传入参数加1的结果"""
return number + 1
print(funname(1))
执行结果:
2
函数调用
调用函数也就是执行函数。如果把创建的函数理解为创建一个有某种用途的工具,那么调用函数就相当于使用该工具。
FunctionName(parameter)
- FunctionName:调用的函数名称
- parameter:可选参数,用于指定各个参数的值。如果需要传递多个参数值,各参数间使用逗号","分隔。如果该函数没有参数,则直接写一对小括号即可。
示例代码:
import re
def filterchar(string):
pattern = r'(黑客)|(抓包)' # 要替换的字符
sub =re.sub(pattern, 'xxx', string) # 如果string中出现pattern中所定义的值,将其替换成'xxx'
print(sub)
filterchar('我喜欢黑客技术,他们经常抓包') # 调用函数
执行结果:
我喜欢xxx技术,他们经常xxx
形式参数和实际参数
- 形式参数:在定义函数时,函数名后面括号中的参数为“形式参数”。
- 实际参数:在调用一个函数时,函数名后面括号中的参数为“实际参数”,也就是将函数的调用者提供给函数的参数称为实际参数。
示意图:
位置参数
位置参数也称必备参数,是必须按照正确的顺序传到函数中,即调用时的数量和位置必须和定义时一样。
如我们有如下一段代码:
def num(a, b, c):
print(a + b + c)
错误传参1:
num(1, 2, "3") # 传入一个字符串让其相加
执行结果:
Traceback (most recent call last):
File "D:/xuexi/python/Demo.py", line 5, in <module>
num(1, 2, "3")
File "D:/xuexi/python/Demo.py", line 2, in num
print(a + b + c)
TypeError: unsupported operand type(s) for +: 'int' and 'str'
错误传参2:
num(1, 2) # 需要3个参数但只传了2个
执行结果:
Traceback (most recent call last):
File "D:/xuexi/python/Demo.py", line 5, in <module>
num(1, 2)
TypeError: num() missing 1 required positional argument: 'c'
注意:
传参时位置也要和定义时的一致,否则调用时就算没有抛出错误,也有可能得到的结果不是你需要的结果。
关键字参数
避免调用函数时不记得需要传参的位置 传入的参数错误,我们可以指定传入参数对应的参数名。
示例代码:
def num(a, b, c):
print(a, b, c)
num(b=2, c=3, a=1)
执行结果:
1 2 3
为参数设置默认值
def FunctionName(parameter = defaultvalue1...)
[FunctionBody]
- FunctionName:函数名称
- parameter = defaultvalue1:可选参数,用于指定向函数中传递的参数,并且为该参数设置默认值为defaultvalue1。
- FunctionBody:可选参数,用于指定函数体,即函数被调用后,要执行的功能代码。
示例代码:
def fun_bmi(height, weight, person='路人'): #定义函数 需要3个参数,其中person默认='路人
"""
功能:根据身高和体重计算BMI指数
:param height:身高,单位:米
:param weight:体重,单位:千克
:param person:姓名
"""
print('【' + person + '】的身高' + str(height) + '米\t体重' + str(weight) + '千克')
bmi = weight / (height * height)
print('【' + person + '】的BMI指数为:', bmi)
print('指标分析:', end='')
if bmi < 18.5:
print('体重过轻')
elif bmi >= 18.5 and bmi < 24.9:
print('正常范围')
elif bmi >= 24.9 and bmi < 29.9:
print('体重过重')
else:
print('肥胖')
fun_bmi(1.8, 85) # 调用函数
执行结果:
【路人】的身高1.8米 体重85千克
【路人】的BMI指数为: 26.234567901234566
指标分析:体重过重
小知识
使用函函数名.__defaults__
可以输出该函数是否有默认参数
print(fun_bmi.__defaults__) # fun_bmi 上面创建的函数
执行结构结果:
('路人',)
可变参数
【*parameter】
def FunctionName(*parameter):
[FunctionBody]
*parameter
这种前面*
的这种形式表示接收任意多个实际参数并将其放到一个元组
中。
示例代码1:
def printDrinks(*drinks):
print('\n我喜欢的饮品有:')
for i in drinks:
print(i)
drinks = ['橙汁', '卡布奇洛', '拉菲']
printDrinks(*drinks) # 调用已存在的列表要在前面加一个*
执行结果:
我喜欢的饮品有:
橙汁
卡布奇洛
拉菲
示例代码2:
def fun_bmi(*person): # 定义函数
"""
:param height:身高,单位:米
:param weight:体重,单位:千克
:param person:姓名
"""
for list_person in person: # 第一次遍历取出('张三', 1.8, 75)
for item in list_person: # 将上面取出的('张三', 1.8, 75)遍历
person = item[0] # 将遍历的结果取第一个
height = item[1]
weight = item[2]
print('\n'+'=' * 13, person, '=' * 13) # 打印姓名加13个等号分割
print('【' + person + '】的身高' + str(height) + '米\t体重' + str(weight) + '千克') # 拼接输出
bmi = weight / (height * height) # 计算BMI
print('【' + person + '】的BMI指数为:', bmi)
print(' 指标分析:', end='') # 不换行打印
if bmi < 18.5:
print('体重过轻')
elif bmi >= 18.5 and bmi < 24.9:
print('正常范围')
elif bmi >= 24.9 and bmi < 29.9:
print('体重过重')
else:
print('肥胖')
value = [('张三', 1.8, 75), ('李四', 1.7, 64)] # 传参的时候是[()]中括号和小括号,那就等于两层所以要两层循环来遍历取值
value2 = [('王五', 1.75, 63)]
fun_bmi(value, value2) # 调用函数
执行结果:
============= 张三 =============
【张三】的身高1.8米 体重75千克
【张三】的BMI指数为: 23.148148148148145
指标分析:正常范围
============= 李四 =============
【李四】的身高1.7米 体重64千克
【李四】的BMI指数为: 22.145328719723185
指标分析:正常范围
============= 王五 =============
【王五】的身高1.75米 体重63千克
【王五】的BMI指数为: 20.571428571428573
指标分析:正常范围
【**parameter】
**parameter
这种前面**
的这种形式表示接收任意多个实际参数并将其放到一个字典
中。
示例代码:
def printsign(**sign):
print()
for key, value in sign.items(): # 遍历字典不要忘了.items()
print(f'【{key}】的星座是:' + value + '\n')
printsign(张三='水瓶座', 李四='射手座')
print('=' * 6 + '第2次调用' + '=' * 6)
dicts = {'one': '天蝎座', 'two': '射手座'}
printsign(**dicts) # 调用已存在的字典要在名称前加**
执行结果:
【张三】的星座是:水瓶座
【李四】的星座是:射手座
======第2次调用======
【one】的星座是:天蝎座
【two】的星座是:射手座
返回值(return)
前面的函数都是调用直接在函数中打印出结果,经常需要函数处理完成后返回一个结果,使用return
。
return value
- value:需要返回的值
示例代码:
def fun_checkout(money):
"""
:param money: 需要计算的金额
:return: 返回金额总计,及折后金额
"""
money_old = sum(money) # 将传入的列表数求和
money_new = money_old
if 500 <= money_old < 1000: # 判断总金额 是否大于500 小于 1000
money_new = '{:.2f}'.format(money_old * 0.9) # 如果满足条件,将总金额乘0.9 格式化小数取值保留两位,赋值给money_new
elif 1000 <= money_old < 2000:
money_new = '{:.2f}'.format(money_old * 0.8)
elif 2000 <= money_old < 3000:
money_new = '{:.2f}'.format(money_old * 0.7)
elif money_old >= 3000:
money_new = '{:.2f}'.format(money_old * 0.6)
return money_old, money_new # 返回总金额 及 优惠后金额
print('\n开始计算....')
list_money = [] # 创建空列表给下面使用
count = 1 # 计数变量
while True: # 永真循环
try: # 捕获非法输入异常
inmoney = float(input(f"请输入第{count}个商品金额,输入后回车,输入0回车结束输入:\n"))
count += 1 # 计数给上一句print使用
if int(inmoney) == 0: # 判断如果用户输入的值是0,直接退出程序
break
else:
list_money.append(inmoney) # 如果输入的参数不是非法字符,将这个参数添加到list_money
except ValueError as e:
print('你输入的格式有误,请重新输入')
money = fun_checkout(list_money) # 调用fun_checkout并将list_money传入
print(f'应付金额:{money[0]}', f'折后金额:{money[1]}') # 打印金额
执行结果:
开始计算....
请输入第1个商品金额,输入后回车,输入0回车结束输入:
9000
请输入第2个商品金额,输入后回车,输入0回车结束输入:
0
应付金额:9000.0 折后金额:5400.00