疑点难点:
思考题:
疑点难点:
1 什么是参数
函数的输入
2 什么是封装
3 如何调用函数
4 什么是形参和实参
5 什么是函数的可读性
6 函数名为什么用小写
7 实参为什么可以是任意的数据类型
因为本质传递的是数据对象的内存的地址,直接量则是会构建一个临时的变量,存储数据的内存地址
8 python为什么是一种动态类型的脚本语言
因为其是在程序执行的过程中解释数据类型的。
9 关键参数的优点
不用按顺序传递参数。
10 参数默认值的赋值顺序(从右到左)
因为传递参数的时候是从按左到右的顺序传递的,可以避免传递的参数覆盖了默认参数
反而又导致后面的形参
11 调用函数时,如何知道需要传递的实参的数量?去查看定义函数的形参?
12 形参同时使用*args和kwargs时,怎么收集实参?元组还是字典?
13 什么是实参解包?
将可迭代对象的元素迭代出来,作为实参传递给形参。
14 为什么lambda表达式难以实现复杂的代码逻辑?
因为表达式只用一行代码
15
思考题:
1 函数的意义:模块化、复用
2 函数的设计:对内(函数体内)要高内聚,对外(函数体之间)要低耦合。职责
3 函数的控制:对内
知识点总结:
理解函数类型
1 函数也是一种数据类型
2 封装重复性的代码,封装就是屏蔽功能实现的细节,只留下接口
函数的主要主要是实现复用,将重复的代码封装到一个模块中。
3 从输入到输出的转换器
4 用关键字def来定义函数,def全写为define(为…下定义)
5 基本语法:
def functionname(paramenter_list):
return values_list
6 paramenter_list表示参数列表,多个参数时,用英文逗号进行分隔
所谓的参数,就是函数的输入
7 return表示停止函数执行(return下的所有代码),并返回值
所谓的返回值,就是函数的输出
8 当返回值有多个时,用英文逗号进行分隔。
9 函数中可以没有return,所以函数可以没有返回值。
10 具名函数的基本属性:函数名,参数,返回值。
函数的调用
1 通过函数名+()的形式来调用函数,调用函数时需要传递参数
()为函数调用符
2 函数定义时的参数为形参(占位使用,相当于变量名),
调用时传递的参数为实参(实际的数据对象,参与函数代码运算的)
实参传递的可以是直接量,可以是变量。
3 函数中返回多个值时,实质为一个元组类型的数据。
使用同等数量的变量名去接收返回值时,相当于元组解包,数据类型为单个返回值的数据类型
元组有自动解包功能,当赋值符号左边只有一个变量,则不解包,赋值为整个返回值,数据类型为元组
函数的命名规范
1 函数名的命名需要符合变量的命名规范
2 具有良好的可读性,能看出该函数的用途,尽量用英文命名。
3 函数命名使用小写,便以区分全局变量的命名与类的命名。多个单词时用进行连接
4 全局变量命名为全部大写,类命名为首字母大写,其他小写。
函数的参数用法
1 位置参数,按从左到右的顺序排序的。在调用函数时,会自动将实参与形参对应起来。
如果无法建立参数之间的一一对应关系,那解释器会抛出类型错误的异常信息。
语法:def max(x, y, z): —> max(x=1, y=66, z=211)
2 关键字参数,将形参当作键名,实参当做键值,进行调用。
语法:function(key=value):def max(x, y, z): —> max(x=1, y=66, z=211)
传递的实参的数量也需要和形参的数量一致(除非形参有默认值)
优点:不需要记形参的位置
3 参数默认值,设置参数默认值后,在不传递对应的实参时,会使用默认值进行替代
语法:deffunctionname(parameter=default_value):def max(x=22, y=11, z=99): —> max_()
在调用有参数
4 引用类型参数,当传递的参数是复合数据类型时,传递的是变量所存储的内存地址的拷贝。
是地址的拷贝,所以函数里的形参和传递的实参指向的是同一块内存地址。
语法:def add_numbers(numbers, number): —> (numbers = [1,2,3]) add_numbers(numbers, 4)
5 可变参数,给形参加上“”或者“**”,表示该形参是可变形参。使用将实参收集为元组
在函数体里面的形参不需要带号
有号的形参,在执行函数调用时,解释器会将该形参对应位置开始的实参全部收集在一个元组里
所以一般有号的形参一般放在最后
语法:def accumulate(numbers): —> accumulate(1,2,3,4,5)
6 可变参数,给形参加上“”或者“**”,表示该形参是可变形参。使用将实参收集为元组
有号的形参,在执行函数调用时,解释器会将该形参对应位置开始的实参全部收集在一个字典里
但是必须以关键字参数进行调用(关键字参数才产生键值对)。所以一般有号的形参一般放在最后
语法:def accumulate(numbers): —> accumulate(number1 = 5, number2=3)
7 *args 与 kwargs 是可变形参名称的通用写法,
args 将实参打包成一个元组类型,**kwargs 将实参打包成一个字典类型
在实际定义函数的过程中,可以沿用这种通用的写法,也可以自行定义可变参数的名称。
8 在定义函数时使用或,是将实参收集到元组或字典中。
而在调用函数时使用*或来进行修饰,则是将实参进行解包。
解包就是将数据集合中的元素取出,然后赋值给对应的参数。
9 使用对可迭代的对象解包,可迭代的对象有:字符串、列表、元组、字典、集合。
对字典、集合类型进行解包时,解包出来的元素为对应的键名,
所以在实际开发中,通常用操作符对字典进行解包。
例如:定义accumulate函数,将参数进行累加
def accumulate()
10 使用对字典进行解包时,字典中的键名与函数中的形参名一一对应,实参即为键名所对应的键值。
字典中的键名与函数中的形参名必须一一对应,否则解释器会抛出类型错误的异常信息。
例如:def accumulate(a, b): —> numbers = {“a”: 1, “b”: 99, “c”: 109},抛出类型错误的异常信息
*lambda表达式
1 语法结构:lambda parameters: expression
paramenters表示函数的形参列表,参数之间以英文逗号隔开,形参列表与具名函数一样,可以为空
形参为空时,
expression表示表达式的代码逻辑,表达式的值会直接返回给函数的调用方,无需用return进行返回
例如:(具名)def accumulate(a, b):return a + b —> (匿名)lambda x, y:x+y
调用时(变量)anonymous_accumulate = lambda x, y:x+y —> (调用)z = anonymous_accumulate(x, y)
通过变量名来调用匿名函数时,和调用具名函数是一样的。
2 lambda表达式与具名函数相比,代码更加简洁,形式上更加简单,只需要一行代码!
但同时也限制了lambda表达式不能实现复杂的代码逻辑。
当需要实现复杂的代码逻辑,还是需要用具名函数的
3 lambda表达式使用灵活,可作为参数传递(属于回调函数),作为返回值传递给调用方,
也可以直接嵌套到其他数据结构中。
4 lambda表达式作为参数的默认值:
例如:定义具名函数accumulate,将参数进行累加。
def accumulate(small,large,add_weight = lambda x:x+1):
‘’’参数add_weight的默认值为一个匿名函数’’’
small = add_weight(small)
return small + large
调用:z = accumulate(1,2) —> small = 1,large = 2, —>
small = add_weight(small) —> small = 2 —> return small + large —> 2+2 —> 4
5 lambda表达式作为返回值(属于闭包函数):
例如:
6 lambda表达式嵌套到字典结构中:
例如:定义一个commands字典,表示各种命令
commands = {“add”: lambda x,y:x+y, “sub”: lambda x,y:x-y}
x = 1
y = 2
执行加法运算:z = commands“add”
执行减法运算:z = commands“sub”
装饰器(一种设计模式)
1 括展,在编程语言上,就是指功能上的扩展。
在面向对象中,一种软件设计模式,是对已有的对象进行功能扩展,而无需改变其结构
2 函数装饰器,在掌握函数装饰器的用法之前,先了解闭包函数。
3 闭包函数,就是函数中定义一个内部函数,相当于父级函数下面再定义一个子级函数
4 内部函数(子函数)可以访问外部(父函数)变量、参数。
5 如何进行扩展,是指在已有的功能基础上扩展新的功能
例如:在弹出欢迎页面之前,先检测用户是否已经登录,如果没有登录,先进入登录页面
6 扩展方案有两种:
第一种,在函数内部增加代码,实现新的功能
第二种,使用闭包函数,与原功能函数共享参数,
7 装饰器、三层架构、回调函数,都是基于解耦合的思想。
8 python中更优雅地使用装饰器,可使用语法糖
装饰器的可变参数
1 参数的一致性,装饰器中的闭包函数参数通常与被装饰对象参数的参数一致。
但被装饰对象的参数类型和数量难以确定,这时可以使用可变参数args,**kwargs
2 给装饰器定义参数
3 装饰器也可以携带参数,通常需要再嵌套一层闭包函数。所以装饰器也有三层结构的
例如:因为我们不知道原功能函数(需要被装饰的函数)的参数类型和数量,所以通常用可变形参
备注:decorator(装饰)、closure(闭包)
def decorator(args,kwargs):
#在第二层传递被装饰的函数对象
def closure_outer(func):
def closure_inner(*args,kwargs)
#在第三层中执行被装饰的对象
func(args,kwargs)
return closure_inner
return closure_outer
生成器
1 函数中使用yield,则该函数对象就是一个生成器
生成器用来实现惰性计算,挂起函数的执行(暂停),返回yield后面表达式的值,
若yield后面没有表达式,则返回None。
2 生成器对象的类型为generator,用type获取
3 生成器对象send方法,传值。
主要是用来传递信息给其他生成器,激活其它生成器的继续执行。使生成器可以交互执行。
4 列表推导式的方式创建生成器对象
5 使用for循环可以自动调用next,继续激活生成器的执行,
最后抛出一个StopIteration错误也会自动处理。
不使用for循环的话,需要手动调用next()函数,抛出的错误也需要手动处理,否则会停止程序的执行
6 next(),启动函数,启动生成器的下次执行。
递归函数*
1 指的是自己调用自己的函数,有直接调用、间接调用。
2 退出边界,可以使用条件控制
3 调用环,类似循环结构
4 递归函数有一个往前回溯的过程
5
常用内置函数
1
2 数学运算函数
绝对值、商和余数(返回为元组类型)、幂运算、四舍六入五成双、
3 序列生成函数
回调函数
1 通过参数调用的函数,传递的是函数地址。
2 可以定制处理逻辑,
给函数设置属性
