一、函数的定义
函数是组织好的,可以重复使用的、实现单一功能的代码。函数中的代码可以多次使用
- 通俗地来说,函数就是一个包裹,一个函数就是一个包裹,每个包裹都有一个功能,只要需要某个功能,只需要拿到包含该功能的包裹即可;
- 你需要调用多少次功能,就使用多少次包裹。
二、函数的组成
- 以上这是我们之前使用过的函数,包含输入数据、处理数据、输出数据等功能;
- 这些函数中都有(),里面存放的是我们要给函数处理的数据。这种数据称之为【函数的参数】;
- 【参数】指的是函数要接受、处理的数据,就是一个变量。
>>> length1=len('神雕侠侣')
>>> print(length1)
4
>>> length2=len('倚天屠龙记')
>>> print(length2)
5
>>>
- 观察以上的代码,参数不一样,结果也会不一样。
三、定义和调用函数
1. 定义函数
定义函数的基本语法如下:
见如下示例:
>>> # 以y=12*x+30为例,定义一个函数
>>> def func(x):
y = 12*x+30
return y
>>> print(func(3))
66
>>>
-
第一行的def的全称为define,即为“定义”的意思:
- “func"是函数的名字,是自己根据功能情况来取名的;
- ”(x)"中的x也是自己取名的,可根据功能进行命名;
- 切记最后面需要跟上英文的冒号
-
def的下一行是函数体,这是函数要实现的功能,即根据x的值,计算12*x+30的结果,同时将结果赋值给y;
-
第三行return是返回的意思,可以指定函数执行完毕后最终会得到什么样的结果,否则计算机是无法判断出函数最终要输出什么结果的。
-
注意事项:
- 函数名:
- 名字能体现函数的功能,一般用小写英文字母和数字、英文下划线组合使用,不要区稀奇古怪、让人摸不着头脑的函数名称,体现自己不专业!
- 不能与Pthon内置函数重名。
- 函数参数:
- 根据函数功能,括号内可以有单个参数、多个参数,也可以没有参数;
- 参数的命名规则与函数命名规则一致;
- 括号是英文括号,后面是英文冒号;
- 函数体:是函数的执行过程,用于完成函数的功能,需要缩进;
- return返回值:需要返回什么数据,则写什么数据;若不需要,可不写。
- 函数名:
定义函数,是将函数中的功能封装好,等待调用
2. 调用函数
>>> def math(x):
y = 30+x
return y
>>> num = math(4)
>>>print(num)
34
>>>
- math(4)就是调用函数,math为定义函数的名字(定义与调用时名字一致);
- 传递参数,4对应函数参数x, 在调用函数时,将10传递给x;
- 在函数体中,y = 30 +4, 得出y的结果为34;
- num用来接收y的值,即num=34。所以,打印出来的最终结果是34。
>>> def order():
x = input('您好,请问你需要什么物品?')
print('跟您确认一下,您需要的物品是%s'%x)
>>> order()
您好,请问你需要什么物品?医用N95口罩
跟您确认一下,您需要的物品是医用N95口罩
>>>
四、函数的进阶使用
1. 函数的类型
- 无名函数。如果是进行一些简单的处理的函数,可以使用关键字“lambda”来记述,这种写法称作无名函数(lambda函数)
def up(s):
return s.upper()
print(up('heelo'))
# 输出结果:
HEELO
lo = lambda s:s.upper()
print(lo('hello'))
# 输出结果:
HELLO
>>> def promotion():
print('江南皮革厂')
print('江南皮革厂倒闭了!')
print('老板带着小姨子跑路了')
print('原价300、500的真皮皮鞋')
print('统统只要88元,只要88元')
print('走过路过,千万不要错过了啊!')
>>> promotion()
江南皮革厂
江南皮革厂倒闭了!
老板带着小姨子跑路了
原价300、500的真皮皮鞋
统统只要88元,只要88元
走过路过,千万不要错过了啊!
>>>
- 如上所示的函数,不需要输入参数,也不需要返回值,运行函数直接打印显示内容即可
- 多个参数的函数(位置参数)。需要注意的是:无论多少个参数,调用函数时参数的顺序要与设置函数时的参数顺序保持一致
>>> def wuxia(jinyong,gulong,huangyi):
print('金庸小说:%s'%jinyong)
print('古龙小说:{}'.format(gulong))
print('黄易小说:{}'.format(huangyi))
print()
>>> wuxia('天龙八部','萧十一郎','大唐双龙传')
>>> wuxia('倚天屠龙记','天涯明月刀','寻秦记')
>>> wuxia('射雕英雄传','流星蝴蝶剑','覆雨翻云')
金庸小说:天龙八部
古龙小说:萧十一郎
黄易小说:大唐双龙传
金庸小说:倚天屠龙记
古龙小说:天涯明月刀
黄易小说:寻秦记
金庸小说:射雕英雄传
古龙小说:流星蝴蝶剑
黄易小说:覆雨翻云
>>>
- 默认参数。切记,**默认参数在位置参数之后。**若在调用函数时,给默认参数的参数赋值了,会覆盖默认参数。
>>> def wuxia(jinyong,gulong,huangyi='寻秦记'):
print('金庸小说:%s'%jinyong)
print('古龙小说:{}'.format(gulong))
print('黄易小说:{}'.format(huangyi))
print()
>>> wuxia('天龙八部','萧十一郎')
>>> wuxia('倚天屠龙记','天涯明月刀')
>>> wuxia('射雕英雄传','流星蝴蝶剑')
金庸小说:天龙八部
古龙小说:萧十一郎
黄易小说:寻秦记
金庸小说:倚天屠龙记
古龙小说:天涯明月刀
黄易小说:寻秦记
金庸小说:射雕英雄传
古龙小说:流星蝴蝶剑
黄易小说:寻秦记
>>>
>>> def wuxia(jinyong,gulong,huangyi='寻秦记'):
print('金庸小说:%s'%jinyong)
print('古龙小说:{}'.format(gulong))
print('黄易小说:{}'.format(huangyi))
print()
>>> wuxia('天龙八部','萧十一郎','大唐双龙传')
>>> wuxia('倚天屠龙记','天涯明月刀','覆雨翻云')
>>> wuxia('射雕英雄传','流星蝴蝶剑','破碎虚空')
金庸小说:天龙八部
古龙小说:萧十一郎
黄易小说:大唐双龙传
金庸小说:倚天屠龙记
古龙小说:天涯明月刀
黄易小说:覆雨翻云
金庸小说:射雕英雄传
古龙小说:流星蝴蝶剑
黄易小说:破碎虚空
- 不定长参数。使用一个星号*加上参数名就接收到了所有参数,无论参数写几个,都能接收到。而返回值就是参数名。
>>> def wuxia(*novel):
return novel
>>> wuxia1 = wuxia('金庸小说:倚天屠龙记', '古龙小说:新鸳鸯蝴蝶梦')
>>> wuxia2 = wuxia('黄易小说:寻秦记', '古龙小说:流星蝴蝶剑', '金庸小说:神雕侠侣')
>>> wuxia3 = wuxia('金庸小说:天龙八部')
>>> print(wuxia1)
>>> print(wuxia2)
>>> print(wuxia3)
- 使用了关键字的参数指定(关键参数)。可以使用伪参数的名字来指定其对应的实参(实参的位置不需要与伪参数保持一致)
def func(a,b):
y = a-b
return y
y = func(b=1,a=3)
print(y)
# 输出结果:
2
def calc(calctype, a, b, c):
if calctype == '和':
x = a + b + c
s = f'{a}+{b}+{c}={x}'
elif calctype == '积':
x = a * b * c
s = f'{a}*{b}*{c}={x}'
else:
s = '???'
return calctype + ':' + s
print(calc('和', b=4, a=8, c=3))
# 输出结果:
和:8+4+3=15
- 将关键参数作为字典来接收,在伪参数之前加”**“就可以将关键参数作为字典来接收
def printdic(**args):
for s, t in args.items():
print(s, ':', t)
printdic(a=90, b=33, c='为空')
# 输出结果:
a : 90
b : 33
c : 为空
- 将字典展开并接收
def printdic(a,b,c):
print(a,b,c)
d = {'a':90, 'b':33, 'c':'为空'}
printdic(**d)
# 输出结果:
90 33 为空
2. 返回多个值
函数不仅可以支持多个参数,也支持返回多个值
>>> import random
>>> print('江南皮革厂倒闭了,最后三天大促,买满80元赠送礼品一份,买满100元还送真皮拖鞋一双,快来参加活动了啊!')
>>> gift = ['真皮皮鞋一只','真皮凉鞋一双','真皮手套一只']
>>> def comp():
money = int(input('您的消费金额是:'))
if money>=100:
choice1 = random.choice(gift)
return choice1,'真皮拖鞋一双'
elif money>=80:
choice2=random.choice(gift)
return choice2
else:
num = 80-money
return '您的消费是%s,还差%s元就可以拿到礼品了,再去消费吧!奥利给~~'%(money,num)
>>> print(comp())
江南皮革厂倒闭了,最后三天大促,买满80元赠送礼品一份,买满100元还送真皮拖鞋一双,快来参加活动了啊!
您的消费金额是:20
您的消费是20,还差60元就可以拿到礼品了,再去消费吧!奥利给~~
>>>
- 以上所示,有3条return语句,每条语句返回的内容都不一样,返回的数量也不一样。这就是返回多个值的用法。
3. 多函数协作
函数封装了独立的功能,一个程序往往是由多个函数构成的,当多个函数协作运行时,就涉及到函数的变量作用域。
- 变量作用域
- 在函数内部声明的变量不能在函数外部访问,函数内部声明的变量为局部变量,其作用域仅限于函数内部。在某个函数内部赋值的变量,只能在当前函数内使用(局部作用域),出了这个函数,它就不起作用了,这就是局部变量
- 全局变量是指在模块范围内的全局变量,其作用域是整个模块。在所有函数之外赋值的变量,可以在程序任意位置使用(全局作用域),这就是全局变量
- 全局变量可以在模块内的函数内部使用,但需要遵循先声明后使用的原则。
- 使用global关键字可以提升函数内部的局部变量为全局变量,当使用global关键字修饰变量时,该变量被提升为全局变量。
- 使用nonlocal声明这个变量不是本地变量(在函数嵌套时使用)
>>> trump = '所有餐厅都要卖兰州拉面'
>>> def KFC():
global harland # global声明全局变量要放在局部变量之前
harland = '所有KFC餐厅都要卖鸡翅'
print('KFC餐厅:%s'%trump)
print('KFC餐厅:%s'%harland)
>>> def Macdonals():
print('麦当劳餐厅:%s'%trump)
print('麦当劳餐厅:%s'%harland)
>>> KFC()
>>> Macdonals()
KFC餐厅:所有餐厅都要卖兰州拉面
KFC餐厅:所有KFC餐厅都要卖鸡翅
麦当劳餐厅:所有餐厅都要卖兰州拉面
麦当劳餐厅:所有KFC餐厅都要卖鸡翅
>>>
4. 函数嵌套
- 如print(type()),这就是一个函数嵌套。代码会先运行print()括号内的函数,再将这个函数结果放到print()函数中执行,打印出来。
- 这样的操作叫做在函数内部调用其他函数。
>>> def hello():
print('欢迎光临KFC')
print('很高兴为您服务')
>>> def order():
print('这里是下单中心')
hello()
print('请您点餐')
print('以上菜单的菜品都有')
>>> order()
这里是下单中心
欢迎光临KFC
很高兴为您服务
请您点餐
以上菜单的菜品都有
五、练习
- 今年业绩不错,餐厅要给员工发奖金,定义一个函数,当输入员工姓名与年限时,打印该员工今年拿多少奖金。规则如下:
- 工作年限<1年的,发1000元奖金;
- 工作年限≥1年但<3年的,发3000元奖金
- 工作年限≥3年的,发10000元奖金 比如输入姓名 ‘老王’,年限‘3’;就会打印出“老王你好,今年你拿10000元奖金”。
>>> name = input('请输入你的姓名:')
>>> year = input('请输入您在公司的工作年限:')
>>> def money():
if int(year) < 1:
return '{},你好。给你发1000元奖金'.format(name)
elif 1 <= int(year) < 3:
return '{},你好。给你发3000元奖金'.format(name)
else:
return '%s,你好。给你发10000元奖金' % name
>>> while True:
if year.isdigit():
print(money())
break
else:
print('错误,请输入数字:')
year = input()
>>>
请输入你的姓名:刘德华
请输入您在公司的工作年限:2年
错误,请输入数字:
2
刘德华,你好。给你发3000元奖金
- 现在餐厅的奖金激励政策变了,变成如下:
- 工作时间<1年的,发放1000元
- 工作年限≥1年但<3年的,发放奖金3000年数(年数四舍五入,输入时只输入整数)如1年半为 30002 = 6000
- 工作年限≥3年的,发放奖金5000年数(年数四舍五入,输入时只输入整数) 如3年为 50003 = 15000
>>> # 设置四舍五入的函数(1位小数)
>>> def myround(num):
if num * 2 >= int(num) * 2 + 1:
return int(num) + 1
else:
return int(num)
>>> # 调用四舍五入的函数,用于根据年限四舍五入设置奖金发多少的函数,
>>> def money(name, year):
if float(year) < 1:
return '%s,你好。给你发1000元奖金' % name
elif 1 <= float(year) < 3:
money = myround(float(year)) * 3000
return '{},你好。给你发{}元奖金'.format(name, money)
else:
money = myround((float(year))) * 5000
return f'{name},你好。给你{money}元奖金'
>>> # 让员工输入名字与工作年限
>>> mingzi = input('请输入你的姓名:')
>>> nianxian = input('请输入在公司的工作年限(数字):')
>>> # 调用奖金发多少的函数
>>> print(money(mingzi, nianxian))
请输入你的姓名:王大锤
请输入在公司的工作年限(数字):3.5
王大锤,你好。给你20000元奖金
- 之前学习过了math.ceil()的方法向上取整,现在通过自己方法,完成向上取整. 用户输入1.1,变成2 用户输入1.5,变成2 用户输入1.9,变成2。
>>> def myceil(num):
if num % 1 == 0:
num = int(num)
else:
num = int(num) + 1
return num
>>> number = float(input('请输入想要取整的数字:'))
>>> print(myceil(number))
请输入想要取整的数字:2.5
3
>>>
- 今天需要和BOSS朋友去吃饭,我们一起打车去市中心,我们想写一个程序,输入坐车公里数,就能自动计算车费。 出租车车费计算方式如下:
- 打车距离在3公里以内,只收起步价15元。
- 距离在3公里~15公里,每1公里加3元。
- 距离超过15公里后,每1公里加5元。
- 不足1公里时,按1公里计算价格。
请完成计价函数。
>>> # 设置向上取整函数
>>> def myceil(num):
if num % 1 == 0:
num = int(num)
else:
num = int(num) + 1
return num
>>> # 设置出租车收费函数
>>> def taxifee(distance,lucheng):
# 当里程小于3公里时,收费起步价15元
if distance < 3:
fee = 15
# 当里程在3-15公里之间时,收费为起步价15元+3公里后的3元/公里
elif 3 <= distance <= 15:
fee = 15 + (distance - 3) * 3
# 当里程大于15公里时,收费为起步价15元+3-15公里的3元/公里+15公里后的5元/公里
else:
fee = 15 + 12 * 3 + (distance - 15) * 5
return '你好,你本次行驶%s公里,打车费用一共是%s元'%(lucheng,fee)
>>> # 让用户输入坐车里程,调用myceil()函数将不足一公里的里程换算成一公里
>>> licheng = float(input('请输入你坐出租车的里程:'))
>>> lucheng= myceil(licheng)
>>> # 调用taxifee()函数计算车费
>>> print(taxifee(lucheng,licheng))
请输入你坐出租车的里程:21.2
你好,你本次行驶21.2公里,打车费用一共是86元
>>>
- 现在龙门镖局需要根据每次的货运量,来计算押运方式:镖师数量恒定,需要押运多少次;押运次数恒定,需要多少镖师。具体的数据为:一个标准为100运量,一名镖师一次运送20个运量,一个标准需要一名镖师运送5次,若只运送一次,则需要5名镖师。
import math
# 设置输入函数
def boss_choice():
# 输入内容
type = int(input('请输入需要的押运方式(1,押运人数恒定;2,押运次数恒定):'))
quantity = float(input('请输入需要押运的运量(1代表标准,可输入小数或倍数):'))
# 当押运人数恒定时,输入即将投入的镖师人数
if type == 1:
others = int(input('请输入投入的镖师人数,请输入整数:'))
# 当押运次数恒定时,输入预计的押运次数
elif type == 2:
others = int(input('请输入押运次数,请输入整数:'))
# 函数返回一个元组
return type, quantity, others
# 设置计算函数
def calculate(data_input):
# 调用参数,参数为元组
type = data_input[0]
quantity = data_input[1]
others = data_input[2]
# 打印计算结果
print('计算结果如下:')
if type == 1:
num = math.ceil(round((100 * quantity) / (20 * others), 2))
print('{:.1f}个标准运量,在投入{}个镖师的情况下,需要押运{}次才能将此趟镖押运完毕.'.format(quantity, others, num))
elif type == 2:
num = math.ceil(round((100 * quantity) / (20 * others), 2))
print('%.1f个标准运量,在%d次押运的情况下,需要%d个镖师才能将此趟镖押运完毕.' % (quantity, others, num))
# 设置主函数,分别调用boss_choice()函数和calculate()函数
def calculate_main():
# 调用boo_choice()给变量赋值
data_input = boss_choice()
# 将变量作为calculate()函数的参数
calculate(data_input)
# 调用主函数
calculate_main()
>>>
# 输出结果如下:
请输入需要的押运方式(1,押运人数恒定;2,押运次数恒定):1
请输入需要押运的运量(1代表标准,可输入小数或倍数):34
请输入投入的镖师人数,请输入整数:10
计算结果如下:
34.0个标准运量,在投入10个镖师的情况下,需要押运17次才能将此趟镖押运完毕.
- 设计一个程序,用来帮助小学生进行算术练习,要求如下
- 可根据需要调整十百千万的范围
- 提供10道加减乘除四种基本运算的题目
- 练习者根据显示的题目回到,程序自动判断是否正确
- 在完成练习后,统计正确数量,错误数量及正确率
def calculate_100(num):
import random, time
name = input('请输入你的姓名:')
right_score = 0
wrong_score = 0
option = ['+', '-', '*', '/']
for i in range(1, 11):
a = random.randint(1, num)
b = random.randint(1, num)
op = random.choice(option)
if op == '+':
c = a + b
elif op == "-":
c = a - b
elif op == '*':
c = a * b
else:
c = round(float(a / b), 2)
print('===================')
print('第%d道题:%d%s%d=?' % (i, a, op, b))
anwser = float(input('请输入你的答案:'))
if anwser == c:
print('回答正确')
right_score = right_score + 1
time.sleep(1)
else:
print('回到错误')
print('正确答案为%r'%c)
wrong_score = wrong_score + 1
time.sleep(1)
else:
print('%s同学,你好。你一共回答了%d道题:正确%d道,错误%d道,正确率%.2f%%' % (
name, i, right_score, wrong_score, right_score / (right_score + wrong_score) * 100))
calculate_100(100)
# 输出结果如下:
请输入你的姓名:王大锤
===================
第1道题:37*36=?
请输入你的答案:34
回到错误
正确答案为1332
===================
第2道题:39/78=?
请输入你的答案:43
回到错误
正确答案为0.5
===================
第3道题:6+35=?
请输入你的答案:43
回到错误
正确答案为41
===================
第4道题:68-90=?
请输入你的答案:44
回到错误
正确答案为-22
===================
第5道题:77/39=?
请输入你的答案:34
回到错误
正确答案为1.97
===================
第6道题:97+80=?
请输入你的答案:23
回到错误
正确答案为177
===================
第7道题:65-15=?
请输入你的答案:54
回到错误
正确答案为50
===================
第8道题:2/29=?
请输入你的答案:23
回到错误
正确答案为0.07
===================
第9道题:22/79=?
请输入你的答案:43
回到错误
正确答案为0.28
===================
第10道题:69-90=?
请输入你的答案:23
回到错误
正确答案为-21
王大锤同学,你好。你一共回答了10道题:正确0道,错误10道,正确率0.00%