python3_函数

函数


参数

可变参数

  • *args 接收若干个位置参数组成tuple, 参数个数可以为0
  • **kwargs 接收若干个关键字参数组成dict

keyword only参数
*号参数后面的普通参数,传入时只能以关键字方式传入
例: def fn(*,x,y) 表示x,y为keyword only参数

参数定义时顺序
位置参数(无默认值参数,默认值参数) -> *arges参数 -> kwargs only参数 -> **kwargs参数
对应形参类型(按可接收实参形式分类)

  • POSITIONAL_ONLY python没有实现
  • POSITIONAL_OR_KEYWORD
  • VAR_POSITIONAL
  • KEYWORD_ONLY
  • VAR_KEYWORD

传参
非可变参数没有默认值,就必须传入对应值,按位置传入参数必须放在按关键字传入参数之前

参数解构: *args, **kwargs

参数默认值

函数对象的默认值放在函数属性中,这个属性伴随着函数对象的整个生命周期
func.__defaults__使用tuple保存所有位置值参数的默认值
func.__kwdefaults__使用字典保存所有keyword-only参数的默认值

默认值如果使用可变类型(list),就可能被修改, 解决方法有两个:
1. x = x[:] 影子拷贝可变类型,重定义,不影响默认值
2. 将默认值设为None(不可变类型),函数内部判断,满足条件,就赋值为可变类型([])


作用域

全局作用域: 模块顶层定义的变量
局部作用域: 仅在函数和类内部可见
自由变量:未在本地作用域中定义的变量
global x 申明本局部作用域内的x为全局变量, 减少global的使用
nonlocal val: 表示声明在上级的某一级作用域中定义,但在不能是全局作用域中定义的变量

函数中的加等异常

var+=1 抛出赋值前被使用异常
因为python中赋值即定义, var = var + 1, 等号右边先算, 但var使用的是本地刚定义的var
变量名的查找顺序是LEGB ,由内向外
Local -> Enclosing -> Global -> Build-in

闭包Enclosing

内层函数引用到外层函数的自由变量,就形成闭包, 内层函数被外层函数返回, 自由变量只能被内层函数访问到

def foo():
    var = 0
    def bar():
        nonlocal var
        var += 1
        return var
    return bar

闭包可以用在装饰器中, 实现单例模型,


递归Recursion

函数直接或间接递归调用自身, 递归一定要有退出条件
当一个逻辑, 重复执行相同的步骤, 只是传入参数值不同时, 就可以使用递归
所有递归都可以转换成循环, 递归是最符合人的思维的逻辑, 递归并不难, 难的是将递归转换成循环

函数执行流程:
依次压栈,创建栈帧,后进先出FILO,依次退出(Return),Return最外层结果

递归不宜过深:
因为压栈会消耗大量系统资源
python作了保护性限制, 查看解释器最大递归深度sys.getrecursionlimit()
修改递归最大深度sys.setrecursionlimit(2000), 超出递归限制, 抛出recursionError


匿名函数lambda

单行函数,只有一条return语句的函数可以写成lambda的形式
lambda表达式既是函数的定义又是函数的引用
例:函数中返回一个lambda函数

def inc():
    def counter():
        n = 0
        while True:
            n += 1
            yield n
    c = counter()
    return lambda :next(c)
foo = inc()
print(foo())
print(foo())

解析式 和 生成器

解析式 是立即计算, 返回结果

  • 列表解析式[x for x in range(10) if x>5], if条件可省略
  • 集合解析式{x for x in range(10)}
  • 字典解析式{x:(x,x+1) for x in range(10)}

可迭代对象 iterable, 拥有__iter__方法的对象, 例:list, tuple等
迭代器 iterator, iter(iterable)生成迭代器, 可以使用next(iterator)函数
生成器 generator, 是特殊的迭代器, 特点: 惰性求值(需要是时候才计算), 只能迭代一次

  • 生成器表达式(x for x in range(10)

生成器函数
yield 表示函数执行暂停到这里,并返回yield后面的值
next(iterator\[, default])函数使生成器函数继续执行,只到下一个yield,如果函数执行结束都找不到yield,则抛出StopIteration, 可以有缺省值,防止报错
Generator函数可以使用return语句, return值不会被返回, 仅表示生成器结束执行
yield from iterable 等价于 iter(iterable)
python使用生成器实现协程coroutine,是在用户空间调度函数的一种实现,比进程,线程轻量级


高阶函数

函数也是对象,可调用的对象, 函数可以作为普通变量、参数、返回值等等

高阶函数
数学概念 y=g(f(x))
数学中定义高阶函数满足以下条件至少一个:

  1. 接受一个或多个函数作为参数
  2. 输出一个函数

内置高阶函数sorted、map、filter, max等

柯里化 指的是将原来接受两个参数的函数变成新的接受一个参数的函数,形成嵌套函数,外部函数负责传入部分参数,并返回内部函数名,内部函数接收剩余参数

装饰器Decorator

装饰器就是一个python解释器的语法糖, 使用@符号和一个可调用对象, 放在需要被增强的函数或类上, 被包装对象作为参数传入, 并将返回值赋给被包装对象的引用
装饰器使用后, 原函数属性会发生改变, 使用functools.wraps, 复制原函数属性
装饰器分为无参装饰器带参装饰器

装饰器的用途:
装饰器是AOP面向切面(方面)编程 Aspect Oriented Programming 的思想的体现
关注点分离, 减少耦合,在不修改原来代码的前提下,给程序动态添加功能,
日志、监控、权限、设计、参数检查、路由等处理

猜你喜欢

转载自blog.csdn.net/qq_33287645/article/details/81364509