函数的高级特性

1.在Python中,函数的递归通常比for循环要慢而且空间消耗大,但是递归的优点是可以遍历任意形状的结构。

2.Python函数是对象,自身存储在内存块中,它可以自由地传递与引用。

  • 函数对象支持一个特殊操作:有括号()以及参数列表执行调用行为
  • 我们可以通用地检查函数对象的某些属性:如.__name__属性、.__code__属性
  • 可以向函数对象附加任意的用户自定义属性,如func.count=0。这样的属性可以用来直接将状态信息附加到函数对象上
  • Python3中,可以给函数对象附加注解。注解不作任何事情,而且注解是可选的,它被附加在函数对象的.__annotaions__属性中。注解的格式为:

    def func(a:'a',b:(1,10),c:float) -> int:
      return a+b+c
    
    • 注解分两种:参数注解紧随形参名字的冒号:之后;返回值注解紧随参数列表的->之后
    • 当出现注解时,Python将它们收集到字典中并附加到.__annotations__属性中
    • 注解可以与默认值同时出现,此时形参形式为c:float=4.0
    • 注解只有在def中有效,在lambda表达式中无效

    函数对象

3.匿名函数:lambda表达式
lambda表达式创建了一个函数对象,它返回该函数对象而不是将其赋值给一个变量名。
创建lambda表达式的语法为:

    labda arg1,arg2,...argN: expression using args
  • lambda表达式是个表达式而不是语句,它能出现在不允许def出现的某些地方,比如参数中
  • lambda表达式返回一个值(一个新的函数对象),可以将它手动赋值给一个变量名

    def总是将一个新的函数对象自动赋值给一个变量名(函数名)

  • lambda的主体是一个单一的表达式,而不是一个代码块。因此lambda通常比def功能简单

    lambda内部甚至不能使用if语句

  • lambda主体中表达式的值就是调用时的返回值,不需要显式return
  • lambda表达式也能使用默认实参
  • lambda表达式主体中遵循def内一样的名字作用域查找法则
    lambda表达式

4.出于可读性要求,最好不要嵌套使用lambda表达式

5.lambda表达式应用于map()filter()reduce()等函数中较多

6.Python是静态检测局部变量的:

  x='global'
  def func():
    print(x)
    x=3

编译时,Python看到了赋值语句x=3,因此决定了在函数内的任何地方,x都是本地变量。但是print(x)时赋值语句并未发生,此时即使全局中有全局的x,也会报错。

  • 任何在函数体内的赋值、import,嵌套def,嵌套类等都受这种行为影响

    即只要有局部变量的定义,无论在函数内哪个地方,其作用域都是本局部作用域全域

    局部作用域的全域效果

7.Python在内部会将每个默认实参保存成对应的对象,附加在这个函数本身。在不同的函数调用期间,这些默认实参会保存同一个对象。因此对于可变对象作为默认实参注意保持警惕。
可变的默认实参