函数
a = '*'
for i in range ( 100 ) :
print ( '锄禾日当午' )
print ( '*********' )
print ( '汗滴禾下土' )
print ( '@@@@@@@@@' )
print ( '谁知盘中餐' )
print ( '+++++++++' )
print ( '粒粒皆辛苦' )
print ( '---------' )
1. 避免代码冗余
2. 提高代码的可维护性
程序员可控的代码量:2W
3. 提高代码的灵活性
4. 提高代码的可重用性
将可重用的逻辑,或者拥有独立功能的代码封装成一起
定义(概念):函数由一组代码构成,完成一个特定的任务
语法:
关键字:def:声明要定义一个函数了
函数的声明:
def 函数名(形式参数):
代码(结构体)
函数的调用:
函数名(实际参数)
调用函数的时候分为函数名+(),但凡在定义之外只要出现括号了,就说明函数被调用了
定义(创建):
1. 定义在全局位置
在没有缩进的位置定义
2. 定义在任何函数的内部
局部性质
流程:
1. 编译流程
1. 通过编译器寻找def关键字,创建了一个函数对象
2. 创建函数体(但是不执行)
2. 执行流程
1. 执行函数的调用
2. 根据函数名跳转到函数定义的位置
3. 执行函数体
4. 执行完毕函数体,流程返回到函数调用处继续向下执行
1. 函数的声明:
def:define
函数名:一定要好好命名(必须自己能看懂)
形式参数
2. 函数体:
内容,函数的功能要实现的核心内容
3. 函数的返回值:
默认返回None
可以返回任意值
可以返回多个值,返回多个值的时候,打包成元组
关键字:def
函数名:全小写
参数:形式参数(可以没有)
函数的参数
1. 形式参数
函数声明的时候,定义的参数
简称:形参
相当于函数的局部变量
2. 实际参数
函数调用过程中,传入的参数
简称:实参
相当于给函数的形式参数赋值
3. 没有定义任何参数
称之为无参
参数和位置有关
1. 实参和形参的位置必须一一对应
2. 位置参数的数量必须一一匹配
3. 位置参数,一旦设定,必须传值。
def func ( a, b) :
print ( a)
func( 1 , 2 )
1. 基于形参
2. 不受位置的影响
3. 实参和形参必须一一对应
def func ( a, b) :
print ( a)
func( b= 2 , a= 1 )
1. 基于形参
2. 如果不传递实际参数,则使用默认值作为实参
3. 如果传递实参,则使用传递后的实参
def func ( a, b) :
print ( a)
func( b= 2 , a= 1 )
可以接收多个参数的形参
1. 基于形参
2. 分类:
1. *args
将接收到的多个参数打包成一个元组
只能通过位置参数来传递
2. **kwargs
将接收的多个参数打包成字典
只能通过关键字参数传值
3. 相同类型的可变长参数,只能有一个
4. 可变长参数可以改名
def func ( ** kwargs) :
print ( kwargs)
func( a= 1 , b= 2 , c= 3 , d= 4 , e= 5 )
1. 关键字参数和位置参数混用
关键字参数只能出现在位置参数之后
原因:参数出现等号的形式,之后的所有参数,都被视为等号形式传值
2. 默认参数和未知参数混用
默认参数只能出现在位置参数之后
3. 可变长参数和位置参数混用:
约定俗成:可变长参数要放在最后并且先 *args 再 **kwargs
1. 必须出现在函数体的第一行
2. 习惯上使用三引号作为文档注释
可以使用单引号或者双引号
3. 函数文档的查看:
可以按着ctrl+鼠标单击该函数查看
查看help(函数名)
函数和过程
return
1. 任何函数必须有返回值
2. 如果函数中不写任何的return,在函数结尾的地方,自动添加一个return None
3. 如果函数中只写了return但是没有携带任何值,自动添加一个None
4. return的作用:
1. 返回流程
2. 返回的时候,可以顺便携带一个值(一定会有返回值)
5. return的值:
1. 任何对象
2. 返回值有且只有一个
3. 如果要返回多个值,打包成元组进行返回
4. 如果返回的是表达式,那么返回的是表达式计算出的值
5. 返回一个函数的调用
函数的返回值就是被调用的函数的返回值(间接获取的返回值)
6. 可以返回一个函数对象
返回形式:return 函数名
注意:被返回的函数并没有执行(没有调用)
注:
pass:是一个关键字,表示不写任何内容
def func ( a) :
if a== '帅' :
return func2
else :
return func3
def func2 ( ) :
return 'my name is zhangyanhao'
def func3 ( ) :
return 'my name is yaojiaqi'
print ( func( a= '更帅' ) ( ) )
作用域:作用范围
1. 全局变量
1. 没有缩进的变量
2. 先定义后使用
3. 作用范围:从定义开始到包含他的代码块结束
2. 局部变量
1. 定义在函数内部的变量
2. 先定义后使用
3. 作用范围:从定义开始到包含他的代码块结束
3. 如果函数内部的局部变量和全局变量发生了命名冲突,在局部访问的是局部变量,在全局使用的是是全局变量(相互不干扰)
如果全局变量和局部变量重名,那么会在局部创建一个同名对象
如果函数内部的同名局部变量的修改影响同名的全局变量,应该使用global
1. global 变量名:声明从该行开始,本层代码的所有该变量,都是全局变量
只对本层有效
a = 1
def func ( ) :
global a
a = 3
print ( a)
func( )
print ( a)
影响上一层的同名的局部变量
1. nonlocal影响上一层的同名局部变量
2. 如果上一层没有对应的局部变量,则报错:
SyntaxError: no binding for nonlocal 'b' found
3. nonlocal和global不能同时声明同一个变量
a = 1
def func ( ) :
a = 2
def func1 ( ) :
nonlocal a
print ( a)
a = 3
print ( a)
print ( a)
func1( )
func( )
print ( a)
没有函数名的函数对象
1. 临时使用一次
2. 函数只使用一次
可以避免命名冲突
关键字:lambda
语法:
lambda 形参:返回值
1. lambda 用于创建函数对象
2. lambda书写的形式:lambda表达式
3. lambda表达式本身的优先级比较低
lambda的效率比较高
函数的构成:
1. 函数的声明+返回值
2. 函数的函数体(过程)
函数和内容是分离的,是两个不同的部分。
1. 可以避免使用函数名,使用方便,代码更加简洁,优雅
2. 提高代码的可读性
print ( ( lambda n: ( '偶数' if n% 2 == 0 else '奇数' ) ) ( int ( input ( '请输入一个整数' ) ) ) )
高级函数
1. 也称之为泛函式编程,是一个编程范式:
可以将一个函数对象作为参数传递给另外一个函数,被传入的函数对象的执行过程,在调用函数中执行。
2. 函数式编程最重要的基础是lambda表达式
lambda表达式可以返回一个函数对象
python2:函数
Python3:类
filter:过滤
1. filter(function or None, iterable)
fuction or None:第一个参数可以是一个函数或者是None
iterable:可迭代对象
1. 如果给了function,则将可迭代对象中的每一个元素,传递给function作为参数,筛选出所有结果为真的值。
2. 如果function没有给出,必须要给None,直接返回iterable中所有为真的值
真值:任何非零的值
假值:零,所有的空
0,False,所有的空
python2:函数
python3:类
map:映射
1. map(func, *iterables)
func:函数
iterables:
运算iterables多个可迭代对象,将每个可迭代对象相同下表的元素,作为参数传递给func,返回一个map对象
函数嵌套调用和递归
1. 一个函数调用另外一个函数,函数的嵌套使用
两个函数之间有没有关系:没有必然联系
1. 分别隶属于两个不同的函数
2. 内嵌函数
3. 自己搞自己:递归
1. 拥有特殊功能的代码,抽取出来,封装为函数
2. 重复使用的代码,抽取出来,封装成函数
只要重复使用>=2次,则封装为函数
判断用户名是否合法:用户登录、用户注册、管理员登录
3. 简化开发流程
函数的嵌套使用:一个函数调用另一个函数
递归:一个函数调用自己
1. 注意:避免无穷递归
解决方案:设置好递归的终止条件 return
2. 报错的原因:
执行原理:函数的无穷递归区别于死循环(递归不是循环!)
循环:代码块级别---在同一个代码块中无限的执行,占用的空间不超过一个代码块,仅仅是一个重复的过程
递归:对象级别---一个对象中可以由多个代码块,对象的内存占用量要远大于一个代码块;每次新调用,都会创建一个新的函数对象,内存是无限累加使用的---无限递归最终会导致内存溢出(内存满了不够用)
小结:循环消耗较少而递归消耗较大
报错的直接原因:超过了最大深度
python为了保护系统的内存,设置了递归的层数,如果超过层数则报错,最大层数996次
3. 递归的使用
1. 递归本身效率很低,一般用于解决难题,比如八皇后
2. 尽量不要用递归,能用递归解决的一定能用循环解决。
递归:汉诺塔(Hanoi)、八皇后