函数
定义
def 关键词开头,空格之后接函数名称和圆括号(),最后还有一个":"。
def 是固定的,不能变,必须是连续的def三个字母,不能分开。
空格 为了将def关键字和函数名分开,必须空。
函数名 函数名只能包含字符串、下划线和数字且不能以数字开头。虽然函数名可以随便起,但我们给函数起名字还是要尽量简短,并能表达函数功能。
括号 是必须加的!
冒号 是必须加的!
注释:每一个函数都应该对功能和参数进行相应的说明,应该写在函数下面第一行。以增强代码的可读性。
调用:就是 函数名() 要记得加上括号。
返回值
return关键字 一旦遇见return,就会结束整个函数
没有返回值
不写return 会默认返回一个None
只写return 会默认返回一个None
return None 和上面情况一样
返回一个值
return 要被返回的值
返回多个值
返回多个值,用一个变量接收 变成一个元组
返回多个值,用多个变量接收
参数
传递参数,简称传参
实际参数,因为这个是实际的要交给函数的内容,简称实参
形式参数,因为在定义函数的时候它只是一个形式,表示这里有一个参数,简称形参
传递多个参数 参数可以传递多个,多个参数之间用逗号分割
位置参数
站在实参角度
按照位置传值
按照关键字传值
位置、关键字形式混着用 位置参数必须在关键字参数的前面,对于一个形参只能赋值一次
站在形参角度 位置参数必须传值
默认参数 将变化比较小的值设置成默认参数
参数陷阱:默认参数是一个可变数据类型
动态参数 *args **kwargs
按位置传值多余的参数都由args统一接收,保存成一个元组的形式
面向过程编程的问题:代码冗余、可读性差、可扩展性差(不易修改)
顺序 位置参数、*args、默认参数、**kwargs顺序定义
def 函数名(参数1,参数2,*args,默认参数,**kwargs):
函数进阶
命名空间
全局命名空间 代码在运行伊始,创建的存储“变量名与值的关系”的空间
局部命名空间 在函数的运行中开辟的临时的空间叫做
内置命名空间 放了python解释器为我们提供的名字:input,print,str,list,tuple...它们都是我们熟悉的,拿过来就可以用的方法。
命名空间的本质 存放名字与值的绑定关系
加载顺序 内置命名空间(程序运行前加载)->全局命名空间(程序运行中:从上到下加载)->局部命名空间(程序运行中:调用时才加载)
取值 在局部调用:局部命名空间->全局命名空间->内置命名空间
在全局调用:全局命名空间->内置命名空间
作用域
作用域就是作用范围
全局作用域 包含内置名称空间、全局名称空间,在整个文件的任意位置都能被引用、全局有效
局部作用域 局部名称空间,只能在局部范围内生效
globals 声明一个全局变量 并且能修改同名的全局变量的值
local
nonlocal关键字 这是一个函数里面再嵌套了一个函数。当使用 nonlocal 时,就声明了该变量不只在嵌套函数inner()里面
才有效, 而是在整个大函数里面都有效。
函数名的本质 函数名本质上就是函数的内存地址
可以被引用
可以被当作容器类型的元素
可以当作函数的参数和返回值
闭包 内部函数包含对外部作用域而非全剧作用域名字的引用,该内部函数称为闭包函数
__closure__ 判断闭包函数的方法
装饰器函数
语法糖
@timer #==> func1 = timer(func1)
装饰器的本质:一个闭包函数
装饰器的功能:在不修改原函数及其调用方式的情况下对原函数功能进行扩展
开放封闭原则
对扩展是开放的
对修改是封闭的
装饰器的主要功能
在不改变函数调用方式的基础上在函数的前、后添加功能。
迭代器与生成器
迭代器
iterable 可迭代的
迭代 可以将某个数据集内的数据,一个挨着一个的取出来。能被for循环的就是可迭代的
可迭代协议 内部实现了__iter__方法
iterator 迭代器
迭代器协议 必须拥有__iter__方法和__next__方法
生成器
生成器函数 常规函数定义,但是,使用yield语句而不是return语句返回结果。yield语句一次返回一个结果,在每个结果中间,挂起函数的状态,以便下次重它离开的地方继续执行
生成器表达式 类似于列表推导,但是,生成器返回按需产生结果的一个对象,而不是一次构建一个结果列表
生成器Generator
本质:迭代器(所以自带了__iter__方法和__next__方法,不需要我们去实现)
特点:惰性运算,开发者自定义
生成器函数
一个包含yield关键字的函数就是一个生成器函数。yield可以为我们从函数中返回值,但是yield又不同于return,return的执行意味着程序的结束,调用生成器函数不会得到返回的具体的值,而是得到一个可迭代的对象。每一次获取这个可迭代对象的值,就能推动函数的执行,获取新的返回值。直到函数执行结束。
send 获取下一个值的效果和next基本一致
只是在获取下一个值的时候,给上一yield的位置传递一个数据 使用send的注意事项 第一次使用生成器的时候 是用next获取下一个值 最后一个yield不能接受外部的值
列表推导式和生成器表达式
生成器表达式 laomuji=('鸡蛋%s' %i for i in range(10)) #生成器表达式
列表推导式 egg_list=['鸡蛋%s' %i for i in range(10)]
multiples = [squared(i) for i in range(30) if i % 3 is 0]
print(multiples)
匿名函数 函数名 = lambda 参数 :返回值