7.函数基础 - 1

7. 函数基础 - 1

什么是函数

函数:一个功能独立的代码块

示例:

# 定义一个函数,能够完成打印信息的功能
def print_info():
    print('------------------------------------')
    print('         人生苦短,我用Python         ')
    print('------------------------------------')

作用

函数在编程中是非常重要的一个知识点,大体功能如下

  • 能够将部分代码划分为一个整体的功能
  • 只需定义函数1次就可以使用N次,可以大大减少了代码的冗余
  • 代码看上去更加整洁美观
示例一:未使用函数的情况
# 输出第1遍 佛祖镇楼
print("                            _ooOoo_  ")
print("                           o8888888o  ")
print("                           88  .  88  ")
print("                           (| -_- |)  ")
print("                            O\\ = /O  ")
print("                        ____/`---'\\____  ")
print("                      .   ' \\| |// `.  ")
print("                       / \\||| : |||// \\  ")
print("                     / _||||| -:- |||||- \\  ")
print("                       | | \\\\\\ - /// | |  ")
print("                     | \\_| ''\\---/'' | |  ")
print("                      \\ .-\\__ `-` ___/-. /  ")
print("                   ___`. .' /--.--\\ `. . __  ")
print("                ."" '< `.___\\_<|>_/___.' >'"".  ")
print("               | | : `- \\`.;`\\ _ /`;.`/ - ` : | |  ")
print("                 \\ \\ `-. \\_ __\\ /__ _/ .-` / /  ")
print("         ======`-.____`-.___\\_____/___.-`____.-'======  ")
print("                            `=---='  ")
print("  ")
print("         .............................................  ")
print("                  佛祖镇楼                  BUG辟易  ")
print("          佛曰:  ")
print("                  写字楼里写字间,写字间里程序员;  ")
print("                  程序人员写程序,又拿程序换酒钱。  ")
print("                  酒醒只在网上坐,酒醉还来网下眠;  ")
print("                  酒醉酒醒日复日,网上网下年复年。  ")
print("                  但愿老死电脑间,不愿鞠躬老板前;  ")
print("                  奔驰宝马贵者趣,公交自行程序员。  ")
print("                  别人笑我忒疯癫,我笑自己命太贱;  ")
print("                  不见满街漂亮妹,哪个归得程序员?")

# 输出第2遍 佛祖镇楼
print("                            _ooOoo_  ")
print("                           o8888888o  ")
print("                           88  .  88  ")
print("                           (| -_- |)  ")
print("                            O\\ = /O  ")
print("                        ____/`---'\\____  ")
print("                      .   ' \\| |// `.  ")
print("                       / \\||| : |||// \\  ")
print("                     / _||||| -:- |||||- \\  ")
print("                       | | \\\\\\ - /// | |  ")
print("                     | \\_| ''\\---/'' | |  ")
print("                      \\ .-\\__ `-` ___/-. /  ")
print("                   ___`. .' /--.--\\ `. . __  ")
print("                ."" '< `.___\\_<|>_/___.' >'"".  ")
print("               | | : `- \\`.;`\\ _ /`;.`/ - ` : | |  ")
print("                 \\ \\ `-. \\_ __\\ /__ _/ .-` / /  ")
print("         ======`-.____`-.___\\_____/___.-`____.-'======  ")
print("                            `=---='  ")
print("  ")
print("         .............................................  ")
print("                  佛祖镇楼                  BUG辟易  ")
print("          佛曰:  ")
print("                  写字楼里写字间,写字间里程序员;  ")
print("                  程序人员写程序,又拿程序换酒钱。  ")
print("                  酒醒只在网上坐,酒醉还来网下眠;  ")
print("                  酒醉酒醒日复日,网上网下年复年。  ")
print("                  但愿老死电脑间,不愿鞠躬老板前;  ")
print("                  奔驰宝马贵者趣,公交自行程序员。  ")
print("                  别人笑我忒疯癫,我笑自己命太贱;  ")
print("                  不见满街漂亮妹,哪个归得程序员?")
示例二:使用函数的情况
# 定义一个函数,完成了独立输出“佛祖镇楼”的功能
def print_fozu():
    print("                            _ooOoo_  ")
    print("                           o8888888o  ")
    print("                           88  .  88  ")
    print("                           (| -_- |)  ")
    print("                            O\\ = /O  ")
    print("                        ____/`---'\\____  ")
    print("                      .   ' \\| |// `.  ")
    print("                       / \\||| : |||// \\  ")
    print("                     / _||||| -:- |||||- \\  ")
    print("                       | | \\\\\\ - /// | |  ")
    print("                     | \\_| ''\\---/'' | |  ")
    print("                      \\ .-\\__ `-` ___/-. /  ")
    print("                   ___`. .' /--.--\\ `. . __  ")
    print("                ."" '< `.___\\_<|>_/___.' >'"".  ")
    print("               | | : `- \\`.;`\\ _ /`;.`/ - ` : | |  ")
    print("                 \\ \\ `-. \\_ __\\ /__ _/ .-` / /  ")
    print("         ======`-.____`-.___\\_____/___.-`____.-'======  ")
    print("                            `=---='  ")
    print("  ")
    print("         .............................................  ")
    print("                  佛祖镇楼                  BUG辟易  ")
    print("          佛曰:  ")
    print("                  写字楼里写字间,写字间里程序员;  ")
    print("                  程序人员写程序,又拿程序换酒钱。  ")
    print("                  酒醒只在网上坐,酒醉还来网下眠;  ")
    print("                  酒醉酒醒日复日,网上网下年复年。  ")
    print("                  但愿老死电脑间,不愿鞠躬老板前;  ")
    print("                  奔驰宝马贵者趣,公交自行程序员。  ")
    print("                  别人笑我忒疯癫,我笑自己命太贱;  ")
    print("                  不见满街漂亮妹,哪个归得程序员?")

# 调用2次函数,每次输出1个佛祖镇楼
print_fozu()
print_fozu()

函数分类

函数根据是否是自己编写可以分为2类

  • 别人已经写好拿来直接用的函数,成为包括Python内置函数或者第三方包中的函数,更省事
  • 开发者自己编写的函数(通常称为自定义函数);根据需要自己编写,更灵活

在整个函数相关知识学习中,我们主要以研究“自定义函数”为主,当“自定义函数”都弄明白了弄懂了,那么用别人的写好的函数就信手拈来了

自定义函数

上面的知识我们知道,函数就是一个独立功能的代码块,想要用函数一定要掌握2块知识

  • 定义函数(即怎样制作函数)
  • 调用函数(即怎样使用函数)

下面我们就来研究函数的定义以及调用

定义函数

定义函数的格式如下:

def 函数名(形参):
   函数体

说明:

  • 函数名:一定有,按照命名规则起个名字,注意Python中建议使用“小写加下划线”的方式,例如print_info而不用PrintInfo
  • 函数体:一定有,就是整个函数真正要执行的代码,注意函数体前面缩进4个空格
  • 形参:可有可无,专门用过来存储调用时传递给函数的数据用的
示例代码

下面定义一个函数,完成打印菜单的功能

def print_menu():
    print("-----------------------")
    print("        欢迎光临        ")
    print("数字1: 黄瓜炒肉")
    print("数字2: 冬瓜炒肉")
    print("数字3: 西瓜炒肉")
    print("数字4: 南瓜炒肉")
    print("数字5: 北瓜炒肉")
    print("-----------------------")

说明:

  • 函数名:print_menu
  • 函数体:第2~9行的代码
  • 形参:无

注意:

  • 定义了函数,这个函数不会被执行。就好比你发明了一个功能,这个功能不能自己用自己,必须等待别人使用才行,如果想让函数执行,就需要调用函数
调用函数

通俗的讲:定义函数相当于打造了一个工具,调用函数相当于使用这个工具完成想要做的事情

调用函数的格式如下

函数名(实参)

说明:

  • 函数名:一定有,想要调用的函数的名字
  • 实参:可有可无,调用函数时给它传递的数据

注意:

  • 调用的函数的名字必须是先定义好的才能够调用,否则会失败
示例代码
# 定义了一个函数,实现打印菜单功能
def print_menu():
  print("-----------------------")
  print("        欢迎光临        ")
  print("数字1: 黄瓜炒肉")
  print("数字2: 冬瓜炒肉")
  print("数字3: 西瓜炒肉")
  print("数字4: 南瓜炒肉")
  print("数字5: 北瓜炒肉")
  print("-----------------------")
  
# 调用函数
print_menu()

运行结果:

-----------------------
        欢迎光临
数字1: 黄瓜炒肉
数字2: 冬瓜炒肉
数字3: 西瓜炒肉
数字4: 南瓜炒肉
数字5: 北瓜炒肉
-----------------------

说明:

  • 函数定义一定要在函数的调用之前,其原因:Python解释器在解析.py文件时会从文件的开头开始解析,会先遇到函数的定义,然后当遇到函数的调用时就知道它在哪,所以函数要先定义才能调用
pass 关键字

如果一个函数,暂时不确定函数体的代码,可以用pass先占用位置,这样即没有语法错误,也能够让开发人员知道 这个函数功能没有实现,可以在后面进行编写

def 函数名():
    pass

示例:要定义4个函数,实现加减乘除的功能,但还不清楚具体功能怎样写,此时就可以用pass

# 定义了4个函数
def add_2_nums():
    pass


def min_2_nums():
    pass


def mult_2_nums():
    pass


def div_2_nums():
    pass


# 分别调用函数
add_2_nums()
min_2_nums()
mult_2_nums()
div_2_nums()

如果想清楚了具体的函数应该怎样实现,那么把pass删除,补上需要的代码即可

# 定义了4个函数
def add_2_nums():
    print("接下来要进行加法操作...")
    num1 = input("请输入第1个数:")
    num2 = input("请输入第2个数:")
    print("%s+%s=%d" % (num1, num2, int(num1) + int(num2)))


def min_2_nums():
    print("接下来要进行减法操作...")
    num1 = input("请输入第1个数:")
    num2 = input("请输入第2个数:")
    print("%s-%s=%d" % (num1, num2, int(num1) - int(num2)))


def mult_2_nums():
    print("接下来要进行乘法操作...")
    num1 = input("请输入第1个数:")
    num2 = input("请输入第2个数:")
    print("%s*%s=%d" % (num1, num2, int(num1) * int(num2)))


def div_2_nums():
    print("接下来要进行除法操作...")
    num1 = input("请输入第1个数:")
    num2 = input("请输入第2个数:")
    print("%s/%s=%d" % (num1, num2, int(num1) / int(num2)))


# 分别调用函数
add_2_nums()
min_2_nums()
mult_2_nums()
div_2_nums()

注意:

  • Python代码规范中提到,定了多个函数,那么函数与函数之间空2行
定义一次执行N次

一个函数可以进行多次调用,每次调用函数时,函数都会从头开始执行,当这个函数中的代码执行完毕后,意味着调用结束了

def test():
    num = 100
    num += 1
    print("在test函数中num=%d" % num)


test()
test()

运行结果:

在test函数中num=101
在test函数中num=101

说明:

  • 第7行调用了第一次test函数,当test函数结束后num为101
  • 第8行调用了第二次test函数,依然会从test函数的开头开始执行,所以结果依然是101

内置函数

内置函数:Python自带的函数,尽情的用,对我们的开发有极大的帮助

Python之所以越来越受到开发者的喜爱,原因之一就是:它丰富的内置函数,基本上需要的功能Python都有了

常用的内置函数如下示例

cmp:

>>> cmp([1, 2], [3, 4])
-1
>>> cmp([1, 2], [1, 1])
1
>>> cmp([1, 2], [1, 2, 3])
-1
>>> cmp({"a":1}, {"b":1})
-1
>>> cmp({"a":2}, {"a":1})
1
>>> cmp({"a":2}, {"a":2, "b":1})
-1

注意:cmp在比较字典数据时,先比较键,再比较值。

len:

>>> len("hello abcdef")
12
>>> len([1, 2, 3, 4])
4
>>> len((3,4))
2
>>> len({"a":1, "b":2})
2

注意:len在操作字典数据时,返回的是键值对个数。

max:

>>> max("hello abcdef")
'o'
>>> max([1,4,522,3,4])
522
>>> max({"a":1, "b":2})
'b'
>>> max({"a":10, "b":2})
'b'
>>> max({"c":10, "b":2})
'c'

del:

del有两种用法,一种是del加空格,另一种是del()

>>> a = 1
>>> a
1
>>> del a
>>> a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined
>>> a = ['a', 'b']
>>> del a[0]
>>> a
['b']
>>> del(a)
>>> a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined

time:

开发中,经常需要打印一些调试的信息,此时就又必须要输出时间,这就需要一些时间函数

import time  # 引入time模块


currentTime = time.time()
print("当前时间戳为:", currentTime)

运行结果:

当前时间戳为: 1598952056.126486

random:

import random

a = random.uniform(1, 5)
print("a =", a)

b = random.randint(10, 50)
print("b =", b)

c = random.randrange(0, 51, 2)
print("c =", c)

运行结果(每次结果都可能不同):

a = 2.018423712655862
b = 14
c = 14

内置函数有很多,在后面的课程中我们根据实际情况加以使用

切记:用到哪些内置函数就查询哪些内置函数,不用背,但要会查询会应用即可

函数说明文档

函数说明文档,顾名思义就是一个对函数说明的信息文档

格式如下:

def 函数名():
    """
    用3对双引号进行包裹,这里就是函数的说明文档,用来对函数的功能,使用方式等进行说明
    以便开发人员能够快速的了解此函数
    """
    pass

函数文档对于我们的意义:

Python内置了很多的函数,但这些函数具体的功能不是我们编写的,我们很难在较短的时间内读懂函数的实现代码

但是只要有了函数说明文档,我们就能快速的知道这个函数的作用,能够大大提高可读性

那怎样用函数的说明文档呢?

Help on built-in function print in module builtins:

print(...)
    print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)
    
    Prints the values to a stream, or to sys.stdout by default.
    Optional keyword arguments:
    file:  a file-like object (stream); defaults to the current sys.stdout.
    sep:   string inserted between values, default a space.
    end:   string appended after the last value, default a newline.
    flush: whether to forcibly flush the stream.

给大家的建议:

编写的代码不仅仅是自己看,还有可能是同事看、同学看、领导看等

当我们的代码中有函数,虽然函数说明文档可写可不写,但是建议大家写上,这样会更加规范

函数参数

引入

阅读如下代码,思考问题:下面的代码实现了2个数的加减乘除,并且把结果打印出来,运行如下代码感觉到哪些地方不太好吗?

# 定义了4个函数
def add_2_nums():
    print("接下来要进行加法操作...")
    num1 = input("请输入第1个数:")
    num2 = input("请输入第2个数:")
    print("%s+%s=%d" % (num1, num2, int(num1) + int(num2)))


def min_2_nums():
    print("接下来要进行减法操作...")
    num1 = input("请输入第1个数:")
    num2 = input("请输入第2个数:")
    print("%s-%s=%d" % (num1, num2, int(num1) - int(num2)))


def mult_2_nums():
    print("接下来要进行乘法操作...")
    num1 = input("请输入第1个数:")
    num2 = input("请输入第2个数:")
    print("%s*%s=%d" % (num1, num2, int(num1) * int(num2)))


def div_2_nums():
    print("接下来要进行除法操作...")
    num1 = input("请输入第1个数:")
    num2 = input("请输入第2个数:")
    print("%s/%s=%d" % (num1, num2, int(num1) / int(num2)))


# 分别调用函数
add_2_nums()
min_2_nums()
mult_2_nums()
div_2_nums()

上述的代码,虽然能够实现2个数的加减乘除,但有个较大的问题:4个函数中每次都需要重新获取这2个数字,我们如果想要计算1和2的加减乘除的结果,就需要输入4遍数字1,4遍数字2,这太麻烦了

想要解决这个问题,大体的思路应该是,在调用加减乘除这4个函数之前先获取要操作的2个数字,然后将这2个数字传递给函数让它们直接用即可而不是每个函数都重新获取

Python中如果在调用函数时,需要将数据传递给函数,这就用到了一个新的"传参数"

使用流程

想要实现”传参数“的功能,只要注意2点即可:

  • 定义函数时()中定义变量,变量的个数根据需要的个数来确定,这些变量的目的是用来存储传递过来的数据。我们把这些变量称之为形参
  • 调用函数时()中写入要传递的数据,可以是常量、表达式、变量等,这些就是要真实传递的数据。我们把这些数据称之为实参

如下示例,展示了调用一个函数将数字100、200都传递给它

def test(num1, num2):  # 形参:调用函数时用来存储数据的变量
    print("传递过来的第1个数是:%d" % num1)
    print("传递过来的第2个数是:%d" % num2)
    print("它们俩的和是:%d" % (num1 + num2))


test(100, 200)  # 实参:在调用函数时传入具体的值

运行结果:

传递过来的第1个数是:100
传递过来的第2个数是:200
它们俩的和是:300
练习

要求:定义一个函数,有3个形参,函数体中要实现的功能为第1个形参+第2个形参-第3个形参 输出结果到终端

参考代码:

def test(num1, num2, num3):
    print(num1+num2-num3)


test(100, 200, 300)

函数返回值

引入

现实生活中的场景:

  • 我给儿子10块钱,让他给我买包烟。这个例子中,10块钱是我给儿子的,就相当于调用函数时传递到参数,让儿子买烟这个事情最终的目标是,让他把烟给带回来然后给你。此时烟就是返回值

开发中的场景:

  • 定义了一个函数,它检测到室内的温度,想一想是不是应该把这个结果给调用者,只有调用者拥有了这个返回值,才能够根据当前的温度做适当的调整

综上所述:

  • 所谓“返回值”,就是函数完成一件事情后,最后给调用者的结果
使用流程

想要用函数的返回结果,我们需要注意2点

  • 定义函数时,需要使用return将结果返回
  • 调用函数时,需要存储这个返回值(当然了语法上来讲可以不存,但一般情况下都会存储,否则还要返回值干什么)

定义函数时,使用return

示例:

def add_2_nums(a, b):
    c = a + b
    return c  # 此时就相当于把变量c的结果返回

定义函数时保存返回值

在本小节刚开始的时候,说过的“买烟”的例子中,最后儿子给你烟时,你一定是从儿子手中接过来 对么,程序也是如此,如果一个函数返回了一个数据,那么想要用这个数据,那么就需要保存

保存函数的返回值示例如下:

# 定义函数
def add_2_nums(a, b):
    c = a + b
    return c

# 调用函数,顺便保存函数的返回值
result = add_2_nums(200, 98)

# 因为result已经保存了add_2_nums的返回值,所以接下来就可以使用了
print(result)

结果:

298
注意点

return实际上有两个作用:

  • 返回数据给调用方
  • 结束函数的执行

猜猜看如下程序执行完毕后,会输出什么?

def test(num1, num2, num3):
    print("test-----1----")
    return 100
    print("test-----2----")
    print(num1+num2-num3)


ret = test(100, 200, 300)
print(ret)

运行结果:

test-----1----
100

可见return不仅有返回一个数据给调用方的功能,还有结束整个函数的作用 换言之:只要在函数体中return后要执行的代码都不会被执行。

return 返回多个值

想一想,如果一个函数中需要返回多个数据,我们改怎么实现呢?

示例一:错误示例

下面的代码,为了能够返回多个数据,用了多个return,想想看行吗?

def create_nums():
    print("---1---")
    return 1  # 函数中下面的代码不会被执行,因为return除了能够将数据返回之外,还有一个隐藏的功能:结束函数
    print("---2---")
    return 2
    print("---3---")


ret = create_nums()
print(ret)

说明:

  • 一个函数中可以有多个return,但是只要有一个return被执行到,那么函数就会结束了,因此后面的return没有什么用处

示例二:

def create_nums():
    print("---1---")
    return [1, 2, 3]

ret = create_nums()  # 此时ret存储了列表[1, 2, 3]
print(ret)

说明:

  • 一个函数中只能有1个return被执行,可用通过return返回列表、元组、集合、字典等从而实现一次性返回多个数据

注意点:

一个函数写多个return也不是没有任何用处,我们可以添加if等代码从而实现不同场景执行不同的return

def create_nums(num):
    print("---1---")
    if num == 100:
        print("---2---")
        return num + 1  # 函数中下面的代码不会被执行,因为return除了能够将数据返回之外,还有一个隐藏的功能:结束函数
    else:
        print("---3---")
        return num + 2
    print("---4---")

result1 = create_nums(100)
print(result1)  # 打印101
result2 = create_nums(200)
print(result2)  # 打印202

四种函数类型

函数根据有没有参数,有没有返回值,可以相互组合,一共有4种

  • 无参数,无返回值
  • 无参数,有返回值
  • 有参数,无返回值
  • 有参数,有返回值
无参数无返回值函数

此类函数,不能接收参数,也没有返回值,一般情况下用来打印提示等类似的功能

def print_menu():
    print('--------------------------')
    print('点菜系统')
    print('1.羊肉涮涮锅')
    print('2.牛肉涮涮锅')
    print('3.猪肉涮涮锅')
    print('--------------------------')
无参数有返回值函数

此类函数,不能接收参数,但是可以返回某个数据,一般情况下像采集数据等功能会用到

# 获取温度
def get_temperature():
    # 这里是获取温度的一些处理过程 处理计算温度的代码省略
    # 为了简单起见,先模拟返回一个数据
    return 24


temperature = get_temperature()
print('当前的温度为:%d' % temperature)
有参数无返回值函数

此类函数,能接收参数,但不可以返回数据,一般情况下对某些变量设置数据而不需结果时用此类函数

def set_age(new_age):
    age = new_age


set_age(18)
有参数有返回值函数

此类函数,不仅能接收参数,还可以返回某个数据,一般情况下这类函数用的很多,毕竟我们调用一个函数还想获取它的结果的情况比较多

# 计算1~num的累积和
def add_nums(num):
    sum_result = 0
    for x in range(1, num + 1):
        sum_result += x
    return sum_result


result = add_nums(100)
print('1~100的累积和为:%d' % result)
总结
  • 函数根据有没有参数,有没有返回值可以相互组合
  • 定义函数时,是根据实际的功能需求来设计的,所以不同开发人员编写的函数类型各不相同

函数之间互相隔离

引入

我们知道函数是一个具有独立功能的代码块,在前面的学习中知道一般情况下把一个个功能都单独做成一个个函数,像之前实现加减乘除就定义了4个函数

在开发时,把独立功能做成一个函数其实就是封装的思想,通过这种方式能够让代码更加整洁

打个比方,当我们离开家乡去远方上学时,往往会大包小包的拎着,每个包中肯定是相类似的物品,这样不仅携带方便在打开包裹取东西时也非常方便,这其实就是”封装“

Python中,根据封装的级别不同,我们会陆陆续续学习到函数、类、对象、模块、包等

"封装"最大的特点就是高内聚低耦合,大白话讲:相关的功能全部封装到函数中(这是高内聚),尽量减少函数与函数之间的依赖(低耦合),也就是说一个函数的改的对其他的函数来说没有影响

因此以后我们在编写代码的时候,谨记“高内聚低耦合”,尽量做到与函数与函数之间没有关系

大家要注意哦“低耦合"可不是"零耦合",也就是函数之间多多少少还是有千丝万缕的关系,大白话讲:函数之间还是有些关系的

函数之间的关系

根据代码的不同,存在3种关系

  • 可能共用同一个变量,会导致一函数添加了数据,另外一个函数删除了数据
  • 可能一个函数的返回值,被当做另外一个函数的参数
  • 可能一个函数体中调用了另外一个函数

共用一个变量

使用全局变量来实现。后面会详细学习

g_num = 0


def test_1():
    global g_num
    # 将处理结果存储到全局变量g_num中
    g_num = 100
    
    
def test_2():
    print(g_num)
    
# 先调用test_1得到数据并且存到全局变量中
test_1()

# 再调用test_2打印test_1()处理过后的数据
test_2()

函数的返回值被当做实参

def test_1():
    return 50
  
def test_2(num):
    print(num)
    
# 先调用test_1获取该函数的返回值
result = test_1()

# 调用test_2时将test_1的返回值传入进去
test_2(result)

函数中调用另外一个函数

使用函数嵌套调用来实现。后面详细学习

def test_1():
    # 通过return将一个数据结果返回
    return 20
  
def test_2():
    # 在test_2函数体中调用test_1并获取test_1的返回值
    result = test_1()
    # 在当前函数体中处理数据
    print(result)
    
    
# 调用test_2完成数据处理
test_2()
总结

函数的功能应该遵循“高内聚,低耦合”

函数之间有关系是肯定的,只要一个函数的改动尽量对另外函数没有影响这就是高品质的函数

至于函数之间的3种关系以及实现方式,需要多练习,当写的代码多了,总结的也多了,相信你的感觉也就到位了

函数嵌套调用

什么是函数嵌套调用?

一种函数中又调用了另外一个函数的方式

def test_1():
    print('--- test_1 start ---')
    print('这里是test_1函数执行的代码...')
    print('--- test_1 end ---')
    
def test_2():
    print('--- test_2 start ---')
    test_1()
    print('--- test_2 end ---')
    
    
test_2()
函数嵌套的作用

能够让函数之间互相使用,增加代码复用性

打个比方,你已经写好了一个功能把它封装为了函数,我再实现另外一个功能的时候发现也需要你写的那个功能函数,此时我不用再写一遍,而是直接将你写的代码拿来用即可,此时我的函数与你的函数都在一个.py文件中,想要用你的函数,我就必须在我写的函数中调用

练习

案例一:

  1. 写一个函数:打印一条横线
  2. 写另外一个函数:打印自定义行数的横线
# 打印一条横线
def print_1_line():
    print("-" * 30)


# 打印多条横线
def print_num_line(num):
    i = 0

    # 因为print_1_line函数已经完成了打印横线的功能,
    # 只需要多次调用此函数即可
    while i < num:
        print_1_line()
        i += 1

# 调用函数
print_num_line(3)

案例二:

  1. 写一个函数:计算三个数的和
  2. 写一个函数:计算三个数的平均值
# 求3个数的和
def sum_3_number(a, b, c):
    return a + b + c  # return 的后面可以是数值,也可是一个表达式


# 完成对3个数求平均值
def average_3_umber(a, b, c):
    # 因为sum_3_number函数已经完成了3个数的就和,所以只需调用即可
    # 即把接收到的3个数,当做实参传递即可
    sum_result = sum_3_number(a, b, c)
    avg_result = sum_result / 3.0
    return avg_result


# 调用函数,完成对3个数求平均值
result = average_3_umber(11, 2, 55)
print("average is %d" % result)

局部变量与全局变量

局部变量
什么是局部变量?

在函数中定义的变量,包括形参变量也是局部变量,只能在定义它的函数中用

def test_1():
    a = 300
    print(f'test_1在修改前的a的值为:{a}')  # f表达式:使用大括号进行占位,要打印的数据直接使用保存数值的变量名称
    a = 200
    print(f'test_1在修改后的a的值为:{a}')
    
def test_2():
    a = 400
    print('函数test_2中的局部变量为: %d' % a)
    
    
test_1()
test_2()
局部变量的作用

我们知道函数要尽量遵循“高内聚,低耦合”也就是一个函数的功能尽量独立,为了实现这些功能就免不了进行各种数学运算,想要运算就需要变量,此时在函数中定义变量的需求也就自然而然的来了

所以说,局部变量一般就是为了实现这个函数中的功能而定义的变量,只能在当前函数中使用,其他函数不能使用

局部变量的特点
  • 局部变量,就是在函数内部定义的变量
  • 形参也属于局部变量
  • 其作用范围是这个函数内部,即只能在这个函数中使用,在函数的外部是不能使用的
  • 每次调用函数时,局部变量都会重新使用,而不是用上一次调用函数时留下的数据
  • 因为其作用范围只是在自己的函数内部,所以不同的函数可以定义相同名字的局部变量(打个比方,把你、我是当做成函数,把局部变量理解为每个人手里的手机,你可有个iPhone12,我当然也可以有个iPhone12, 互不相关)
全局变量
什么是全局变量?

一种在函数外部定义的变量,可以在所有函数中共用

# 定义全局变量
a = 100

def test_1():
    a = 300  # 局部变量
    print(f'test_1修改前a的值为: {a}')
    a = 200
    print(f'test_1修改后a的值为: {a}')

def test_2():
    print(f'test_2获取全局变量的值为: {a}')

    
test_1()
test_2()
全局变量的作用

局部变量它的作用范围就只能在定义它的函数中用,而有时为了能够在多个函数之间共用某个数据,此时就有了全局变量

打个比方:有2个兄弟各自有手机,各自有自己的小秘密在手机里,不让另外一方使用(可以理解为局部变量);但是家里的电话是2个兄弟都可以随便使用的(可以理解为全局变量)

全局变量的使用方式

定义全局变量:

# 定义全局变量
a = 100

获取全局变量:

# 定义全局变量
a = 100


def test1():
    print(a)  # 虽然没有定义变量a但是依然可以获取其数据


# 调用函数
test1()

修改全局变量:

如果一个函数中需要修改全局的值,此时我们需要用global进行声明

# 定义全局变量
a = 100

def test1():
    print(a)  # 虽然没有定义变量a但是依然可以获取其数据


def test2():
    global a  # 如果一个函数中需要修改全局的值,此时我们需要用globa进行声明
    a += 1  # 修改全局变量
    print(a)

# 调用函数
test1()
总结
  • 在函数外边定义的变量叫做全局变量
  • 全局变量能够在所有的函数中进行访问
  • 当函数内出现局部变量和全局变量相同名字时,函数内部中的 变量名 = 数据 此时理解为定义了一个局部变量,而不是修改全局变量的值
  • 如果在函数中出现global 全局变量的名字 那么这个函数中即使出现和全局变量名相同的变量名 = 数据 也理解为对全局变量进行修改,而不是定义局部变量
  • 如果在一个函数中需要对多个全局变量进行修改,那么可以使用

函数案例:学生管理系统

# -*- coding:utf-8 -*-
# @FileName: test.py
# @Time    : 2022/9/26 2:05 下午
# @Author  : 顾安


import time
import os

# 定一个列表,用来存储所有的学生信息(每个学生是一个字典)
info_list = []


def print_menu():
    print("---------------------------")
    print("      学生管理系统 V1.0")
    print(" 1:添加学生")
    print(" 2:删除学生")
    print(" 3:修改学生")
    print(" 4:查询学生")
    print(" 5:显示所有学生")
    print(" 6:退出系统")
    print("---------------------------")


def add_new_info():
    """添加学生信息"""
    new_name = input("请输入姓名:")
    new_tel = input("请输入手机号:")
    new_qq = input("请输入QQ:")

    for temp_info in info_list:
        if temp_info['name'] == new_name:
            print("此用户名已经被占用,请重新输入")
            return  # 如果一个函数只有return就相当于让函数结束,没有返回值

    # 定义一个字典,用来存储用户的学生信息(这是一个字典)
    info = dict()

    # 向字典中添加数据
    info["name"] = new_name
    info["tel"] = new_tel
    info["qq"] = new_qq

    # 向列表中添加这个字典
    info_list.append(info)
    print(info_list)


def del_info():
    """删除学生信息"""
    del_num = int(input("请输入要删除的序号:"))
    if 0 <= del_num < len(info_list):
        del_flag = input("你确定要删除么?yes or no: ")
        if del_flag == "yes":
            del info_list[del_num]
    else:
        print("输入序号有误,请重新输入")


def modify_info():
    """修改学生信息"""
    modify_num = int(input("请输入要修改的序号:"))
    if 0 <= modify_num < len(info_list):
        print("你要修改的信息是:")
        print("姓名:%s, 手机:%s, QQ:%s" % (info_list[modify_num]['name'],
                                       info_list[modify_num]['tel'], info_list[modify_num]['qq']))
        info_list[modify_num]['name'] = input("请输入新的姓名:")
        info_list[modify_num]['tel'] = input("请输入新的手机号:")
        info_list[modify_num]['qq'] = input("请输入新QQ:")
    else:
        print("输入序号有误,请重新输入")


def search_info():
    """查询学生信息"""
    search_name = input("请输入要查询的学生姓名:")
    for temp_info in info_list:
        if temp_info['name'] == search_name:
            print("查询到的信息如下:")
            print("姓名:%s, 手机:%s, QQ:%s" % (temp_info['name'], temp_info['tel'], temp_info['qq']))
            break
    else:
        print("没有您要找的信息....")


def print_all_info():
    """遍历学生信息"""
    print("序号\t\t姓名\t\t手机号\t\tQQ")
    i = 0
    for temp in info_list:
        # temp是一个字典
        print("%d\t\t%s\t\t%s\t%s" % (i, temp['name'], temp['tel'], temp['qq']))
        i += 1


def main():
    """用来控制整个流程"""
    while True:
        # 1. 打印功能
        print_menu()

        # 2. 获取用户的选择
        num = input("请输入要进行的操作(数字): ")

        # 3. 根据用户选择,做相应的事情
        if num == "1":
            # 添加学生
            add_new_info()
        elif num == "2":
            # 删除学生
            del_info()
        elif num == "3":
            # 修改学生
            modify_info()
        elif num == "4":
            # 查询学生
            search_info()
        elif num == "5":
            # 遍历所有的信息
            print_all_info()
        elif num == "6":
            # 退出系统
            exit_flag = input("亲,你确定要退出么?~~~~(>_<)~~~~(yes or no): ")
            if exit_flag == "yes":
                break
        else:
            print("输入有误,请重新输入......")

        input("\n\n\n按回车键继续....")
        os.system("clear")  # 调用Linux命令clear完成清屏


# 程序的开始
main()

posted @ 2023-03-08 15:06  这人穷的很  阅读(31)  评论(0编辑  收藏  举报