文章目录
函数(function)
- 函数也是一个对象;
- 函数用来保存一些可执行的代码,并在需要的时候对这些语句进行多次的调用;
- 函数常用于实现某种功能;
定义函数
格式:
def 函数名 ([形参1…形参n]):
代码块
注意 函数需要调用的时候才会执行;
调用函数
格式:
函数名()
注意 直接使用函数名是使用的函数对象,而不是对函数进行调用;
函数的参数
- 在定义函数时可以在函数的()里定义数量不等的形参;多个形参之间用逗号,隔开;
- 形参,即形式上的参数,定义形参就相当于在函数内部声明了变量,但是不赋值;
- 实参,即实际上的参数,如果函数定义时指定了形参,调用时就必须指定实参;
- 实参传的是多少,函数中形参就是多少;
默认参数
- 定义形参时,可以为形参指定默认值
- 指定默认值后,如果用户传递了对应的实参则默认值不起作用,如果用户没有传递对应的实参则默认值纳入计算;
实参的传递方式
位置参数
- 位置参数:将对应位置的实参赋值给对应位置的形参,如第一位上的实参将值赋值给第一位的形参;
关键字参数
- 传递实参时直接指定赋值给那个形参;
- 位置参数和关键字参数可以混合使用,但关键字参数需在位置参数后面
实参类型
- 传递实参时,实参可以传递任意类型的对象,如int、str、函数对象、字典等;
不定长参数(参数的装包)
- 在定义形参时,可以在形参前面加上一个*,这样这个形参就会获取所有的实参,并将所有的实参值保存在元组中;
- 带*参数只能有一个,带*参数不是必须写在形参中最后,但在带*参数后面的形参只能以关键字参数传递参数;
- 如果形参以*,开头则要求所有实参必须以关键字参数的形式传递;
- **参数可以接受其他的关键字参数,并将其形参和实参作为键值对存储在一个字典中;
- *参数只能接受位置参数,不能接受关键字参数
- **参数只能有一个,只能写在形参的最后;
参数的解包
- 传递实参时,在序列类的参数前加*,则会自动将序列中元素依次作为参数传递给实参;
- 通过**来对字典进行解包,如果用*则会将其键作为实参传给形参;
返回值
- 函数的返回值,就是函数执行之后的结果;可以通过return指定函数的返回值;
- return后面接什么,函数就返回什么;return后可以接任意对象,函数也可以;
- return后面不写东西或不写return,则相当于return None;
- 在函数中,return后的代码不会执行;return相当于函数的结束符;
return 后面的print没有执行;
help(函数名)
- help(函数名)可以查看python中函数的用法;
文档字符串
- 在定义函数时,可以在函数内部编写文档字符串,文档字符串就是函数的说明;
- 编写了文档字符串后,就可以用help()来查看函数的说明
- 在函数第一行编写的字符串就是文档字符串;
- 在函数的形参上和返回值可以对其类型进行注释,即可以让别人清楚可以使用哪些类型;
- a,b可以用int,c可以用bool,返回值为int型;
作用域
- 作用域就是变量生效的区域;
全局作用域
- 全局作用域在程序执行时创建,在程序执行结束时销毁;
- 所有函数以外的区域都是全局作用域;
- 在全局作用域中定义的变量,都属于全局变量,全局变量可以在程序的任意位置被访问;
函数作用域
- 函数作用域在函数调用时创建,在调用结束时销毁;
- 函数每调用一次就会产生一个新的函数作用域;
- 函数作用域中的变量时局部变量,只能在函数内部访问;
- 作用域小的变量可以访问作用域大的变量,即在函数作用域中可以访问全局作用域;反之不能;
- 在函数作用域使用全局变量,用global关键字来声明变量;
变量的查找
- 在使用变量时,会优先在当前作用域中寻找该变量,如果有就直接使用;如果没有则往上一级作用域寻找,全局作用域都没有就报错;
命名空间(namespace)
- 命名空间指变量存储的位置,每一个变量都需要存储到指定的命名空间中;
- 命名空间实际上是一个字典,专门用来存储变量的字典;
- 每一个作用域都会有一个与它对应的命名空间;全局命名空间用来保存全局变量;函数命名空间用来保存函数中的变量;
locals()
- locals()用来获取当前作用域的命名空间;
- 在全局作用域中使用locals()则获取全局命名空间,以字典形式返回;
- 在函数作用域中使用locals()则获取函数命名空间,以字典形式返回;
globals()
- globals()用于在任意位置获取全局命名空间;
递归式函数
- 递归就是自己调用自己;
- 递归式函数就是在函数中自己调用自己;
无穷递归
效果类似死循环;
- 递归是解决问题的一种方式,其解决问题思想是将大问题分解为一个个的小问题,知道问题无法分解,再去解决问题;
递归式函数的两要素
基线条件
当满足基线条件时,递归就不在执行了;
递归条件
将问题继续分解的条件;
示例
下面用递归求取任意数阶乘来讲解递归函数:
求整数n的阶乘:
因为n!=n*(n-1)!=n*(n-1)*(n-2)!=n*…*1!;
所以1!=1就时求阶乘的基线条件;
而n不等于时就递归,直到n=1;
高阶函数
-
python中,函数是一等对象;
-
一等对象的特点:
- 对象在运行时创建;
- 能赋值给变量或作为数据结构中元素;
- 能作为参数传递;
- 能作为返回值返回;
-
高阶函数
-
接受函数作为参数,或者将函数作为返回值的函数值是高阶函数;
如,后面的filter()、map()、sort()、sorted()是将函数作为参数,将函数作为返回值的是闭包; -
当使用函数作为参数时,就是将函数中代码传递进目标函数中;
将函数名作为参数传给另一个函数,将fun2传给fun1即将fun2中代码块传给fun1
-
filter()
作用
- 可以将序列中过滤出符合条件的元素,并存到一个新的序列;
参数
- 函数,根据该函数来过滤序列(可迭代结构)(函数作为参数)
- 序列,需要过滤的序列(可迭代结构)
返回值
- 过滤后的新序列(可迭代结构)
map()函数
作用
- 对可迭代对象中所有元素做指定操作,然后将其添加到一个新对象中返回;
参数
-
函数,即对元素的指定操作;(函数作为参数)
-
对象,需要进行操作的可迭代对象;
如,对列表中每个元素+1后返回;
sort()
-
对列表中的元素进行排序;
-
默认直接比较列表中元素大小;
-
sort()可以接受一个关键字key作为参数,key可以为函数,设置函数后,每次都会将列表中一个元素作为参数来调用函数,并使用函数返回值来比较函数大小;(函数作为参数)
len()返回字符串长度,sort根据字符串长度比较每个元素的的长度,按升序排列;
sorted()
- 与sort用法一致,sorted可以对任意序列进行排序;sorted排序不会影响原来的对象,会排序后返回一个新对象;
- sorted()也可以传入key,用法与sort一致;(函数作为参数)
闭包
- 将函数作为返回值返回叫的高阶函数叫闭包;
- 形成闭包的条件
- 函数嵌套
- 外部函数将内部函数以返回值返回
- 内部函数需使用外部函数的变量
- 闭包可以保证数据的安全性
fn也是一个函数,是调用fun1()后的返回值fun2,fn是fun1()函数内定义的,所有fn能访问fun1()里的变量;fun1()中变量a只有fun2()能访问;
匿名函数(lambda 表达式)
lambda函数
- lambda函数表达式用于创建一些简单的函数;
语法
lambda 参数列表:返回值
以下两种形式是一样的;
调用形式
- (lambda a,b:(a+b))(实参,实参)
- 将lambda表达式赋值给一个变量,如fn1=lambda a,b:a+b
装饰器
- 使用装饰器可以在不修改原来函数的前提下对函数进行功能扩展