课堂笔记11(函数、函数的参数、函数的返回值、函数作用域、函数递归)

函数

函数介绍

函数:是组织好的,可重复使用的,用来实现单一、或相关联功能的代码段。

函数作用:提高应用的模块性代码的复用性
例如:将一个代码重复10遍,如果直接复制粘贴过于繁琐和多【不方便】,用函数可以提高代码复用性,直接函数设置好重复的次数即可。

函数只有在调用的时候才会执行。
调用方式:函数名+()。如果()内需要参数则填写参数。

自定义函数

已经接触过的内置函数
len() 【内置函数,直接调用传参数来达到求参数的长度目的】
print()
input()

我们也可以自定义函数

定义规则:

  • 函数代码块def 关键词开头,后接函数标识符名称和圆括号()
  • 圆括号中间可以放入参数
  • 函数内容以冒号起始,并且缩进

样式:在这里插入图片描述
def:开头
function_name:函数名称尽量使用下划线命名法
param:参数(可以写也可以不写)
():跟在函数名后面的必须要有
print:属于缩进函数内容可以写其他内容

pycharm中的演示:

以重复1000次九九乘法表为例,
先自定义九九乘法表的函数。
multi_table就是九九乘法表调用函数。
在这里插入图片描述
注意⚠️:第一层for循环要缩进,如果是顶格,则不能算是函数内的内容。

在这里插入图片描述
注意⚠️:函数只有调用时候才会执行,如果不调用不会执行。通过函数名+()为调用,

将函数建立好后,可以使用循环进行重复调用达到多次打印输出。
比如for循环、while循环。
下图为for循环调用1000次的样式。
在这里插入图片描述

函数的参数

函数的参数分为:

  • 形参与实参
  • 可变类型参数与不可变类型参数
  • 位置参数
  • 关键字参数
  • 默认值参数
  • 可变长度参数
形参与实参

形参:函数定义中的参数,没有实际的值,通过别人赋值后才有意义,相当于变量。

实参:调用函数时传入的参数,是一个实际存在的参数。
图中图中
1的param是def自定函数中的参数,符合形参。是定义中的参数没有实际的值。

2的param是函数调用时候所用的参数,属于实参
下图为例子:可以发现有形参和实惨是一种对应关系,
在这里插入图片描述

小结

形参与实惨是对应关系。
如果实参是位置参数需要和形参一一对应包括个数。
默认参数需要形参进行指定,这样实参可以不写。
定义内如果有形参,那么调用的时候需要填写实惨。
如果形参在定义的时候进行了特殊形参设置【调用时候可以不填写实惨的情况】,那么可以不填写实惨。
具体可见总结。

可变类型参数与不可变类型参数

不可变类型参数:在函数体内对变量重新赋值,相当于重新开辟了一块内存来保存值。

在这里插入图片描述

可变类型参数:在函数体内可以改变原有的值。
在这里插入图片描述
函数调用执行顺序
先执行21. 22行之后进入14行的函数内部代码(22行函数调用)
在这里插入图片描述

位置参数

位置参数:实参与形参顺序一一对应,个数也一致,而不论变量名。
在这里插入图片描述

关键字参数

关键字参数:以形参=实参形式指定,不论参数位置。
如图所示:在b行中,不管白色的num2 和num1位置如何颠倒,当红色(形参)=白色(实参)关键词指定后,顺序不影响a行中的顺序,和执行结果。
同位置参数的区别点。
在这里插入图片描述

默认值参数

默认值参数:形参处进行赋值,所以当调用时不传参数‘()’就默认使用形参处的值。当调用时传了该参数,则覆盖掉默认参数。

如图所示:在形参中b=2则为默认值参数。
当调用的时候实参只输入了a 则默认b为2 ,所以结果为3 2
在这里插入图片描述
当实参中传了一个b的数据时,形参中的b的数据被覆盖了为10
在这里插入图片描述

可变长度参数:

*args接收时会转为元组数据类型
**kwargs接收时会转为字典数据类型
可变长度参数的长度不限,同时参数可以传,可以不传,但是会将内容统一打包转为元组或者字典。
注意⚠️:一定要输入“✳️”或者“✳️✳️”

图片内容分解:
url:是位置参数,必须要传的参数。
params=None :默认参数,可以不传,默认为None。
**kwargs:可变长度参数。以字典形式传,可以传可以不传,可以传单个也可以多个。
在这里插入图片描述

*args:

自定一个可变长度参数:args,调用函数,但不传入参数时,可以得到一个空的元组
在这里插入图片描述
在调用函数时候放入参数可以得到元组形式的参数内容。
在这里插入图片描述
注意⚠️:
1、自定函数的形参如果是(*args,a=1)【可变长度参数,默认参数】
这时候,实参输入(a,b,c,a=10)

2、(*args,a=1,b)【可变长度参数,默认参数,位置参数】
这时候,实参输入(a,b,c,a=10,b=23)
在python3.0之后,args参数后面只能跟关键字参数【形参=实参】。
在这里插入图片描述
上图a=20 即为通过关键字参数方式重新给a=2进行了赋值。b=4 即为关键词参数指定b的传参。

**kwargs:

同args的区别是:实参需要传入键值对,然后形参会将它打包成字典。
如图所示:是一个空字典
在这里插入图片描述

实参传参方式:
在这里插入图片描述

解包(拆包)

假设定一个元组为tu=(1,2,3)
如果想要a=1 b=2 c=3时可以拆包
a,b,c,=(1,2,3)
这个过程就是拆包。

之前*args就类似打包的过程,现在就是拆包的过程。

在实参中加个*就是拆包,注意形参中要设置拆包形式,但是也要注意接收的变量数。
如果形参只有a,b 而tu中是123三个元素,那么会报错,因为没有一一对应。在这里插入图片描述

函数的返回值

函数的返回值介绍:当两个函数之间,想要互相使用到内部变量时,就可以应用到函数的返回值。
将a从1中传出,之后2接收再传入进去,这个过程就是返回值。

函数的返回值定义:

  • 使用 return 关键字返回内容
  • 内容返回到函数调用处
  • 函数体中没有 return语句时,函数运行结束,则默认返回None,也被称为隐含返回值【之前一些函数之间print可以发现得到的结果是None是因为没有设置return,所以默认为None】
    在这里插入图片描述在这里插入图片描述
    小细节:
    多个定义函数,先将函数定义都完成,最后统一调用函数
函数多个返回值
  • 当执行函数体内代码时,遇到第一个return就将指定值返回到函数调用处,也就是执行到return这行代码,后面的都不执行
  • 多个返回值,用逗号隔开,但默认为元组
    在这里插入图片描述
    上图所示:多个return只执行第一个,一旦将东西返回出去后,就不会再继续执行函数内部的代码了。

在这里插入图片描述
上图所示:要返回多个返回值的时候统一打包,返回一个元组,为一个值。【将三个数变为一个值】

在这里插入图片描述
上图所示:通过拆包的形式将多个返回值一一打印输出。

函数作用域

函数作用域介绍:python中,程序的变量并不是在哪个位置都可以访问的,访问权限决定于这个变量是在哪里赋值的。

变量的作用域决定了在哪一部分程序可以访问哪个特定的变量名称。python的作用域一共有四种。

  1. L(local):局部作用域,即函数中定义的变量
  2. E(enclosing):嵌套的父级函数的局部作用域,即包含此函数的上级函数的局部作用域,但不是全局的
  3. G(global):全局变量,就是模块级别定义的变量
  4. B(build-in):内建作用域,系统固定模块里的变量,比如:int()等

in、循环控制 都是没有作用域的
所以,如下图所示:在if里面的a 在for中的i都是可以之间在外部访问打印输出得到内容的。
在这里插入图片描述
函数的作用域,在函数内部的a 和外部的a变量名相同,本质不同,所以在外部不能像if 、循环控制那样在外部调用打印输出,而是报错。
在这里插入图片描述
解析如下图所示:
在这里插入图片描述
当函数内没有局部变量时:取全局变量。
当函数内部有局部变量时:优先局部变量。
在这里插入图片描述

global关键字(函数内部修改全局变量声明)

当需要在函数内部直接修改全局变量时,可以将函数内部的局部变量通过global关键字声明为全局变量
在这里插入图片描述
下图报错原因分析:
图中圈中的a是为局部变量名,而方块的a理想中是调用全局变量,整体理想就是在函数内部运用全局变量,但是在系统中无法区分全局变量还是局部变量,所以报错。
在这里插入图片描述下图中:将之前圈中的a变为了c,系统就能区分,c为局部变量,而a函数内没有,就去全局中提取变量。就不会有报错情况发生。
在这里插入图片描述
解决方法一:初始局部变量
在函数内初始一个局部变量。
即重新建立一个局部变量。

方法二:声明局部变量为全局变量
global 声明a就是全局的a
直接在函数内部,用全局变量。
在这里插入图片描述

作用域优先级

作用域大小排名:
built- in(内建作用域)>global(全局作用域,模块级别)>enclosing(嵌套父级函数作用域)>local(局部作用域)

作用域优先级:
local(局部作用域)>enclosing(嵌套父级函数作用域)>global(全局作用域,模块级别)>built- in(内建作用域)
在这里插入图片描述

B(build-in):内建作用域

内建作用域:系统固定模块里的变量,只要在python环境中即可使用。
如int():a = int(1,2,3)
command点击int,可以发现显示的模块是:builtins模块。
在这里插入图片描述

G(global):全局变量、L(local):局部作用域、E(enclosing):嵌套的父级函数的局部作用域

全局变量:就是模块级别定义的变量
例如:a = 11

L(local):局部作用域,即函数中定义的变量
例如:c = 6

E(enclosing):嵌套的父级函数的局部作用域,即包含此函数的上级函数的局部作用域,但不是全局的
例如:b = 5
在这里插入图片描述
备注:如果函数嵌套不止两层,比如三层。
永远最里面的那一层(上图中是def inner()那一层)的变量是局部变量
其他层级(上图def outer()那层)的变量都是嵌套父级作用域。

在嵌套函数中如果要声明父级作用域是局部作用域,不是用global关键字,而是用nonlocal关键字
在这里插入图片描述

global关键字与nonlocal关键字区别

global:是声明局部作用域的变量取的是全局作用域中的同名变量。
nonlocal:是声明嵌套的父级作用域的变量取的是局部作用域中的同名变量。

函数调用执行顺序
  1. 代码从上至下执行
  2. 函数只有在调用的时候才会执行
  3. 函数执行完毕,则返回函数的调用处
    在这里插入图片描述

递归函数Func(args)

递归:Func(args)递归函数,直接或间接调用函数本身

递归注意点:

  1. 在函数内部调用自己。
  2. 递归没有结束条件,一定要自己设定结束条件,终止函数调用。
  3. 能够用递归实现的,都可以用循环实现,递归效率低,所以很少使用。

实现阶乘的方法:
方法一:循环控制
在这里插入图片描述

方法二:递归函数Func(args)
在这里插入图片描述
设定结束条件:if语句设置
在这里插入图片描述
方法三:reduce
reduce:从python3开始不再是内置文件,而是在内置模块中的,所以需要导入。从functools中导入。f
在这里插入图片描述
注意:只能两两传入,因为实参在封装过程中只能传入两个。
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/yuuisei/article/details/112558648