Python第八课:函数(def)

一、函数的定义

函数是组织好的,可以重复使用的、实现单一功能的代码。函数中的代码可以多次使用

  • 通俗地来说,函数就是一个包裹,一个函数就是一个包裹,每个包裹都有一个功能,只要需要某个功能,只需要拿到包含该功能的包裹即可;
  • 你需要调用多少次功能,就使用多少次包裹。

二、函数的组成

点击关闭图片

  • 以上这是我们之前使用过的函数,包含输入数据、处理数据、输出数据等功能;
  • 这些函数中都有(),里面存放的是我们要给函数处理的数据。这种数据称之为【函数的参数】;
  • 【参数】指的是函数要接受、处理的数据,就是一个变量。
>>> 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是返回的意思,可以指定函数执行完毕后最终会得到什么样的结果,否则计算机是无法判断出函数最终要输出什么结果的。

  • 注意事项:

    • 函数名:
      1. 名字能体现函数的功能,一般用小写英文字母和数字、英文下划线组合使用,不要区稀奇古怪、让人摸不着头脑的函数名称,体现自己不专业!
      2. 不能与Pthon内置函数重名。
    • 函数参数:
      1. 根据函数功能,括号内可以有单个参数、多个参数,也可以没有参数;
      2. 参数的命名规则与函数命名规则一致;
      3. 括号是英文括号,后面是英文冒号;
    • 函数体:是函数的执行过程,用于完成函数的功能,需要缩进
    • 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()

江南皮革厂
江南皮革厂倒闭了!
老板带着小姨子跑路了
原价300500的真皮皮鞋
统统只要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. 今年业绩不错,餐厅要给员工发奖金,定义一个函数,当输入员工姓名与年限时,打印该员工今年拿多少奖金。规则如下:
    • 工作年限<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. 现在餐厅的奖金激励政策变了,变成如下:
    • 工作时间<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元奖金
  1. 之前学习过了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
>>>
  1. 今天需要和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>>>
  1. 现在龙门镖局需要根据每次的货运量,来计算押运方式:镖师数量恒定,需要押运多少次;押运次数恒定,需要多少镖师。具体的数据为:一个标准为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次才能将此趟镖押运完毕.
  1. 设计一个程序,用来帮助小学生进行算术练习,要求如下
    1. 可根据需要调整十百千万的范围
    2. 提供10道加减乘除四种基本运算的题目
    3. 练习者根据显示的题目回到,程序自动判断是否正确
    4. 在完成练习后,统计正确数量,错误数量及正确率
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%
发布了15 篇原创文章 · 获赞 0 · 访问量 254

猜你喜欢

转载自blog.csdn.net/fightingoyo/article/details/104096358