第九关:函数 - 0入门到进阶(附练习题) | Python基础语法

下面小编就整理了在编程中,比较常用的【函数】0入门到进阶的用法。

Python基础语法 - 专栏链接

手把手教你如何入门,如何进阶。

目录

1.  函数的概念

2.  函数的形参、实参、默认参数、不定长参数

3.  函数的作用

4.  函数返回多个值、不返回值

5.  函数的变量作用域

6.  函数的嵌套

练习题

联系我们,一起学Python吧


1.  函数的概念

前面学习过的循环是减少代码重复的一种手段,那么接下来要学习的函数则是Python里增强代码重用性最有力的工具,它的定义是:函数是组织好的、可以重复使用的、用来实现单一功能的代码。

随着我们想要实现的功能越来越复杂,代码可能会有几百上千行,这样对写代码和读代码都是一个挑战。如果将一个程序用函数拆分成多个独立的子任务来完成,就会让代码结构变得清晰许多。

第1行:def 的意思是定义(define),math 是【函数名】(自己取的),再搭配一个英文括号和冒号,括号里面的x是参数(参数名也是自己取)。

第2行:def 下一行开始缩进的代码就是函数要实现的功能,也叫【函数体】。这里的功能就是:根据x计算出一个值y。

第3行:return 语句是返回的意思,可以指定函数执行完毕后最终会返回什么值或表达式,否则计算机是无法判断出函数最终要输出什么结果的。

定义函数的语法并不难,但有些注意事项一开始要特别注意才能少踩坑,请你仔细阅读下。

# 函数名:1. 名字最好能体现函数的功能,一般用小写字母和单下划线、数字等组合
#      2. 不可与内置函数重名(内置函数不需要定义即可直接使用)
def math(x):
# 参数:根据函数功能,括号里可以有多个参数,也可以不带参数,命名规则与函数名相同
# 规范:括号是英文括号,后面的冒号不能丢
    y = 5*x + 1
# 函数体:函数的执行过程,体现函数功能的语句,要缩进,一般是四个空格
    return y
# return语句:后面可以接多种数据类型,如果函数不需要返回值的话,可以省略

定义了函数,那怎么调用呢?

def math(x):
    y = 5*x + 1
    return y
# math(2)调用math函数,并传入实参:2。最后赋值给result,并打印结果。
# 因为math函数 有return返回值,所以result就能够接收到这个返回值 y。
result = math(2)
print(result)
# 11

2.  函数的形参、实参、默认参数、不定长参数

def math(x,z=3):
    y = 5*x + z + 1
    return y
result = math(2)
print(result)
# 14

上面例子中,math(x) 中的 x 就是形参,math(2) 中的 2 就是实参。

形参:就是形式参数,它是形式上的,并没有真正的值。它只是一个标识,表明这里有个叫 x 的参数。

实参:即实际参数,它是在调用函数时真正传进去的值。

上面的例子中实参是 2,传给函数后形参 x 的值就被赋值为 2 了。

默认参数:直接在定义函数的时候给参数赋值。这里的 z=3 就是默认参数,直接赋值好的,函数体直接调用的。需要注意的是:默认参数必须放在位置参数之后。

不定长参数:一个星号*加上参数名,它的返回值也比较特殊:

def menu(*lesson):
    return lesson

lessons = menu('python','java','php','c')
#括号里的这几个值都会传递给参数barbeque

print(lessons)
print(type(lessons))
# ('python', 'java', 'php', 'c')
# <class 'tuple'>

你会发现函数返回的是这样的结果:('python', 'java', 'php', 'c'),我们用type()函数可以知道这种数据类型叫作元组(tuple)。

比如说我们最熟悉的print()函数,它完整的参数其实是长这样的:

print(*objects, sep = ' ', end = '\n', file = sys.stdout, flush = False)

可以看到第一个参数objects带了 * 号,为不定长参数——这也是为什么print()函数可以传递任意数量的参数。其余四个为默认参数。

 

3.  函数的作用

在我们没有学过函数之前,我们计算 y = 5x + 1 可能会像下面这样写:

x = 2
y = 5 * x + 1

如果有多个 x 的输入,你会这样写:

x1 = 1
y1 = 5 * x1 + 1

x2 = 2
y2 = 5 * x2 + 1

x3 = 3
y3 = 5 * x3 + 1
...

你应该也注意到了,我们写了很多相似的重复代码。而我们学会了函数之后,就可以这样写:

def math(x):
  y = 5 * x + 1
  return y

y1 = math(1)
y2 = math(2)
y3 = math(3)
...

可以看到,代码非常精简,需要计算多少次、用多少次函数直接调用就好了。

4.  函数返回多个值、不返回值

函数返回多个值情况:

def shop(money):
    if money < 5:
        return '饮料'
    elif 5 < money < 10:
        return '花生', '瓜子'

print(shop(6))
print(type(shop(6)))
# ('花生', '瓜子')
# <class 'tuple'>

# <class 'tuple'>表示返回的数据类型又是我们刚才提到的元组。在这个例子中,该元组是由两个元素构成的。
# 元组和列表一样,可以通过索引来提取当中的某个元素
result = shop(6)        # result此时是一个元祖
print(result[0])
print(result[1])
# 花生
# 瓜子

函数不返回值情况:

其实函数的参数和返回值都不是必选项,是可以没有的。

def say_hello():
  print('hello~')

调用上面的 say_hello() 函数会打印出 hello~,只是单纯的打印内容而已,不需要参数和返回值。

当然你可以给我们的 say_hello() 函数加功能,对指定的人说你好:

def say_hello(name):
  print('hello~' + name)

say_hello('python')
# hello~python

所以,要不要参数完全根据你的需求来定,需要就加,用不到也可以没有。

5.  函数的变量作用域

在 Python 中变量作用域分为 全局作用域局部作用域 两种,两种作用域下的变量分别是 全局变量局部变量

对初学者来说,你可以简单地理解为:函数内定义的变量是 局部变量,函数外定义的变量是 全局变量

# 这里的 rule 在函数外是全局变量
rule = '965 工作制'

def busy_company():
  # 这里的 rule 在函数内是局部变量
  rule = '996 工作制'
  print('忙碌企业:' + rule)

def common_company():
  # 函数内没有定义 rule,会去全局变量里找
  print('常规企业:' + rule)

busy_company()
common_company()
# 忙碌企业:996 工作制
# 常规企业:965 工作制

这里要提醒同学注意,调用函数时,Python 会优先在局部作用域内寻找变量,找不到再去外层的全局变量寻找,如果都找不到则报 NameError 的错误。

def busy_company():
  rule = '996 工作制'
  print('忙碌企业:' + rule)

def common_company():
  print('常规企业:' + rule)

busy_company()
# 输出:忙碌企业:996 工作制
common_company()
# 报错:NameError: name 'rule' is not defined
print(rule)
# 报错:NameError: name 'rule' is not defined

此时的 rule 属于busy_company()函数内的局部变量,common_company()函数是无法访问的。

解决方法:只需要在局部变量前加上 global 关键字即可,这样在全局作用域访问局部作用域的变量,我们来看个例子:

def busy_company():
  global rule  # 声明为全局变量
  rule = '996 工作制'
  print('忙碌企业:' + rule)

def common_company():
  print('常规企业:' + rule)

busy_company()
# 输出:忙碌企业:996 工作制
common_company()
# 输出:常规企业:996 工作制
print(rule)
# 输出:996 工作制

加了 global 关键字后,相当于我们向大家宣布,自己家里的东西大家可以一起共用。上面例子中 busy_company() 里的 rule 就成了全局变量,函数外也能使用,便不会再报错了。

还有另一种情况,如果在局部作用域修改全局变量的值,也要在函数的局部作用域中的变量前加上 global 关键字,我们用代码来体会一下:

rule = '996 工作制'

def common_company():
  global rule  # 声明为全局变量,没有声明,重新赋值无效
  rule = '965 工作制'
  
common_company()
print(rule)
# 输出:965 工作制

来总结一下:函数内是局部作用域,函数外是全局作用域。局部作用域的变量是局部变量,只能在该函数内使用,全局作用域的变量是全局变量,大家都可以使用。这就像国家规定的 965 工作制是普适的,但有些节奏快的忙碌企业内部会规定 996 工作制,但只在其企业内有效。

如果想让局部变量变成全局变量也是可以的,只需在使用变量前加上一句 global 变量名 即可。

6.  函数的嵌套

在一个函数内部调用其他函数。

def find_book():
    print('查询所有图书')
    pass        # pass 不做任何事情,一般用做占位语句,测试使用
    # 代码块

def lend_book():
    print('借书')
    pass        # pass 不做任何事情,一般用做占位语句,测试使用
    # 代码块

def return_book():
    print('还书')
    pass        # pass 不做任何事情,一般用做占位语句,测试使用
    # 代码块

def welecome():
    print('欢迎进入【图书系统】')

def main():
    welecome()
    number = input('输入数字:1.查看所有图书。2.借书。3.还书。4.退出系统。')
    if number == '1':       # 根据用户输入的数字,调用不同的函数,函数嵌套函数
        find_book()    # 查看图书函数
    if number == '2':
        lend_book()    # 借书函数
    if number == '3':
        return_book()    # 还书函数

main()

我们可以看到:在主函数 main() 中调用不同的函数,一个函数 find_book() 负责查看图书,一个 lend_book() 负责借书,一个return_book() 负责还书,每个函数都有自己的代码块,需要用哪个就可以重复调用,达到一个完整的 【图书系统】。

练习题

同学们,先自觉练习,答案在公众号,公众号回复暗号【答案】即可。

1. 下列代码的运行结果是?

def func_1():
  print("热干面")

def func_2():
  food = "螺蛳粉"

func_1()
func_2()
func_1()

A. 热干面
   螺蛳粉
B. 热干面
   热干面
C. 螺蛳粉
   螺蛳粉
D. 螺蛳粉
   热干面

2. 下列代码中,b 和 d 分别是什么类型的参数?

def func(a, b):
  print(a + b)
# 5
c = 2
d = 3
func(c, d)

A. 形参,实参
B. 形参,形参
C. 实参,实参
D. 实参,形参

3. 下列代码的运行结果是?

a = 2
def number():
    a = 1

number()
print(a)

A. 2
B. 1
C. a
D. None

4. 下列代码的运行结果是?

def func(a, b, c = 4):
	print(a + b + c)

func(1, 2, 3)

A. 5
B. 6
C. 7
D. 8

5. 这段代码能运行吗?

def func(a=4, b):
  print(a + b)

func(3, 5)

A. 能运行,结果为8
B. 能运行,结果为9
C. 能运行,无打印结果
D. 不能运行,报错

6. 下列代码的运行结果是?

count = 1

def func():
  global count
  if count > 0:
    count = count + 1

func()
print(count)

A. 0
B. 1
C. 2
D. 3

7. 下列代码的运行结果是?

a = 1
a = 2

def func(a=4):
  print(a)

func(3)

A. 1
B. 2
C. 3
D. 4

8. 做一个简易的抽奖程序。

# 终端打印结果

开奖倒计时 3
开奖倒计时 2
开奖倒计时 1
************
恭喜小明中奖!

要求:人员名单赋值给列表,传入该列表到choujiang()函数。

提示1:可利用time模块的sleep(1)方法,使程序延迟执行,呈现倒计时效果。

提示2:可利用random模块的choice()方法,随机从列表中取值。

联系我们,一起学Python吧

每周每日,分享Python实战代码,入门资料,进阶资料,基础语法,爬虫,数据分析,web网站,机器学习,深度学习等等。


​微信群(关注「Python家庭」一起轻松学Python吧)

​QQ 群(983031854

发布了16 篇原创文章 · 获赞 95 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/qq_34409973/article/details/104750368