# 函数概述

# 自定义函数

  • 当程序调用函数时,def 语句才会创建一个新的函数对象,并赋予其名字。

    • python和其他需要编译的语言不一致,def是可执行语句,这意味着函数知道被调用前都是不存在的。
  • 如果我们在函数内部调用其他函数,函数间哪个声明在前、哪个在后就无所谓,因为 def 是可执行语句,函数在调用之前都不存在,我们只需保证调用时,所需的函数都已经声明定义

  • Python 函数支持函数的嵌套。

    • 函数的嵌套能够保证内部函数的隐私。
    • 合理的使用函数嵌套,能够提高程序的运行效率。
  • 不能在函数内部随意改变全局变量的值,除非使用global关键字,在函数中改变全局变量的值会报错

  • 嵌套函数可以使用nonlocal关键字访问和修改外部函数定义的变量

    • nonlocal关键字表明时非局部也非全局
  • 在 Python 中,函数是一等公民(first-class citizen),函数也是对象。我们可以把函数赋予变量。

  • 函数可以作为参数,传递进入另一个函数中

  • 函数的返回值可以是函数对象(闭包)

def get_message(message):
    return 'Got a message: ' + message


def root_call(func, message):
    print(func(message))
  
root_call(get_message, 'hello world')

# 输出
Got a message: hello world

# 函数式编程

  • 函数式编程,是指代码中每一块都是不可变的(immutable),都由纯函数(pure function)的形式组成。这里的纯函数指函数本身相互独立、互不影响,对于相同的输入,总会有相同的输出,没有任何副作用。

  • Python 主要提供了这么几个函数:map()、filter() 和 reduce(),通常结合匿名函数 lambda 一起使用来实现函数式编程。

    • map(function, iterable) 函数,表示对 iterable 中的每个元素,都运用 function 这个函数,最后返回一个新的可遍历的集合。
    • filter(function, iterable) 函数,表示对 iterable 中的每个元素,都使用 function 判断,并返回 True 或者 False,最后将返回 True 的元素组成一个新的可遍历的集合。
    • reduce(function, iterable) 函数,它通常用来对一个集合做一些累积操作,表示对 iterable 中的每个元素以及上一次调用后的结果,运用 function 进行计算,所以最后返回的是一个单独的数值。
    • all() 函数用来判断一个迭代器的元素是否全部为 True,如果是则返回 True,否则就返回 False.
  • python的函数式编程一般效率是最优的(直接调用底层C代码)

# 不是函数式编程
def multiply_2(l):
    for index in range(0, len(l)):
        l[index] *= 2
    return l

# 是函数式编程
def multiply_2_pure(l):
    new_list = []
    for item in l:
        new_list.append(item * 2)
    return new_list

l = [1, 2, 3, 4, 5]
new_list = map(lambda x: x * 2, l) # [2, 4, 6, 8, 10]

l = [1, 2, 3, 4, 5]
new_list = filter(lambda x: x % 2 == 0, l) # [2, 4]

l = [1, 2, 3, 4, 5]
product = reduce(lambda x, y: x * y, l) # 1*2*3*4*5 = 120