函数
- 代码的一种组织形式,一个函数一般完成一项特定的功能
- 函数使用:函数需要先定义;使用函数,俗称调用
- 定义一个函数,只定义的话不会执行
- def关键字,后面跟一个空格
- 函数名,自己定义,起名需要遵循变量命名规则,约定俗成,大驼峰命名只给类用
- 后面括号和冒号不能省略,括号内可以有参数
- 函数内所有代码有缩进
函数的参数和返回值
- 参数:负责给函数传递一些必要的数据或者信息
- 形参(形式参数):在函数定义的时候用到的参数没有具体值,只是一个占位符号,称为形参
- 实参(实际参数):在调用函数的时候输入的值;返回值:函数的执行结果
- 返回值:函数的执行结果
- 使用return关键字
- 如果没有return,默认返回一个None
- 函数一旦执行return语句,则无条件返回,即结束函数的执行
参数详解
-
参数的分类:普通参数,默认参数,关键字参数,收集参数
-
普通参数:
-
定义的时候直接定义变量名
-
调用的时候直接把变量名或者值放入指定位置
def 函数名(参数1,参数2,...) 函数体 # 调用 函数名 # 调用的时候,具体值参考的是位置,按位置赋值
-
-
默认参数:
-
形参带有默认值
-
调用的时候,如果没有相对应行参数值,则使用默认值
def func_name(p1=v1,p2=v2,...): func_block #调用1 func_name() #调用2 value1=100 value2=200 func_name(value1,value2)
-
-
关键字参数:
-
语法:
def func(p1=v1,p2=v2,...) func_body 调用函数: func(p1=value1,p2=value2,...)
-
比较麻烦,但也有好处:
- 不容易混淆,一般实参和形参只是按照位置一一对应,容易出错
- 使用关键字参数,可以不考虑参数位置
-
-
收集参数:
-
把没有位置,不能和定义时的参数不位置相对应的参数,放入一个特定的数据结构中
-
语法:
def func(*args): func_body 按照list使用方式防蚊args得到传入的参数 调用: func(p1,p2,p3,...)
-
参数名args不是必须这么写,但是我们推荐直接用args,约定俗成
-
参数名args前需要有星号
-
收集参数可以和其他参数共存
-
举例:
#收集参数代码 #函数模拟一个学生进行自我介绍,但具体内容不清楚 #args把他看成一个list def stu(*args): print('Hello大家好,我自我介绍一下,简单说两句:“) #type函数作用是检测变量的类型 print(type(args)) for item in args: print(item) stu("Liuying",18,"wangxiaojing","single") stu(“周大神”) 运行结果: Hello大家好,我自我介绍一下,简单说两句: <class,'tuple'> Liuying 18 wangxiaojing single Hello大家好,我自我介绍一下,简单说两句: <class,'tuple'> 周大神
-
-
收集参数实例:说明收集参数可以不带任何实参调用,此时收集参数为空tuple
stu() 运行结果: Hello大家好,我自我介绍一下,简单说两句: <class,'tuple'>
-
收集参数之关键字收集参数,把关键字参数按字典格式存入收集参数
-
语法:
def func(**kwargs): func_body #调用: func(p1=v1,p2=v2,p3=v3,...)
-
kwargs一般约定俗成
-
调用的时候,把多余的关键字参数放入kwargs
-
访问kwargs需要按字典格式访问
-
收集参数混合调用的顺序问题
- 收集参数,关键字参数,普通参数可以混合使用
- 使用规则就是:普通参数和关键字参数优先
- 定义的时候一般找普通参数,关键字参数,收集参数tuple,收集参数dict
-
收集参数的解包问题
-
把参数放入list或者字典中,直接把list/dict中的值放入收集参数中
-
语法:收集参数的解包问题
def stu(*args): print("哈哈哈") #n用来表示循环次数,主要用来调试 n = 0 for i in args: print(type(i)) print(n) n+ = 1 print(i) l=["LiuYing",19,23] #此时args的表示形式是字典内一个list类型的元素,即arg=("LiuYing",19,23),很显然跟我们最初的想法违背 #此时的调用,我们就需要解包字符,即调用的时候前面加一个星号 stu(*l) 运行结果: 哈哈哈 <class 'str'> 0 LiuYing <class 'int'> 1 19 <class 'int'> 2 23
-
同理,dict类型收集参数一样可以解包,但是对dict类型进行解包,需要用两个星号进行解包
返回值
- 函数和过程的区别:有无返回值
- 需要用return显示返回内容,如果没有返回,则默认返回None。推荐写法,无论有无返回值,最后都要以return结束
函数文档
- 函数的文档的作用是对当前函数提供使用相关的参考信息
- 文档的写法:
- 在函数内部开始的第一行使用三引号字符串定义符
- 一般具有特定格式
- 文档查看
- 使用help函数,形如help(func)
- 使用_doc_
变量作用域
- 变量有作用范围限制
- 分类:按照作用域分类
- 全局(global):在函数外部定义
- 局部(local):在函数内部定义
变量的作用范围
- 全局变量:在整个全局范围都有效
- 全局变量在局部可以使用(即函数内部可以访问函数外部定义的变量)
- 局部变量:在局部范围可以使用
- 局部变量在全局范围无法使用
LEGB原则
- L(Local)局部作用域
- E(Enclosing function local)外部嵌套函数作用域
- G(Global module)函数定义所在模块作用域
- B(Buildin)python内置模块的作用域
- 提升局部变量为全局变量,使用global
globals,locals函数
- 可以通过globals和locals显示出局部变量和全局变量
eval()函数
-
把一个字符串当成一个表达式来执行,返回表达式执行后的结果
-
语法
eval(string_code,globals=None,local=None) 示例:x=100 y=200 z1=x+y z2=eval("x+y") print(z1) print(z2) 运行结果: 300 300
exec()函数
-
跟eval功能类似,但是不返回结果
-
语法
exec(string_code,globals=None,local=None) 示例:x=100 y=200 z1=x+y #1.注意字符串中引号的写法 #2.比对exec执行结果和代码执行结果 z2=exec("print('x+y':x+y)") print(z1) print(z2) 运行结果: x+y:300 300 None
递归函数
- 函数直接或者间接调用自身
- 优点:简洁,理解容易
- 缺点:对递归深度有限制,消耗资源大
- python对递归深度有限制,超过限制报错
- 在写递归程序的时候,一定要注意结束条件