疑点难点:

    思考题:
    疑点难点:
    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 可以定制处理逻辑,
    给函数设置属性
    image.png