由若干语句组成的语句块、函数名称、参数列表构成,它是python中组织代码的最小单元,通常按照代码的功能划分,将其封装成一个个的功能函数。

Python中的函数定义函数的语法如下:
def 函数名(参数列表):
函数体(代码块)
[return 返回值]

函数的作用:
结构化编程对代码的最基本的封装,一般按照功能组织一段代码
封装的目的为了复用,减少冗余代码
代码更加简洁美观、可读易懂

参数:

  • 位置参数:按照形参定义的顺序依次传入实参
  • 关键字参数:使用形参的名字来传入实参(key=value),如果使用了形参名字,那么传参顺序就可和形参的定义顺序不同
  • 形参的默认值定义语法为在形参后跟上一个值
  • 可变参数:一个形参可以匹配任意个实参。注意可变参数是对形参而言的,实参没有可变参数。
    可变参数分为“位置可变参数”和“关键字可变参数”
    (位置可变参数的语法如下:
    在形参前使用*表示该形参是可变参数,可以接收多个实参
    收集到的多个实参被自动封装为一个tuple元祖
    关键字可变参数的语法如下:
    关键字可变形参的名字前使用必须使用两个星号 符号,表示该形参可以接收多个关键字参数
    收集到的多个实参名称和值被自动封装为一个字典。)
  • keyword-only参数的概念:
    如果在一个星号参数后,或者一个位置可变参数后,出现的普通参数,实际上该参数已经不是普通的参数了,而是keyword-only参数。给keyword-only形参传参时,只能通过关键字参数传递,否则抛语法异常。

参数列表参数的一般顺序是:
普通参数、缺省参数(缺省参数不能写在普通参数前面)、可变位置参数、keyword-only参数(可带缺省值)、可变关键字参数

返回值:
结束函数调用、并返回“返回值”。
Python规定所有的函数都必须要有返回值,如果没有显式的定义return语句,那么python就会隐式的调用return None。一个函数可以存在多个return语句,但是只有最前面的一条可以被执行。
函数不能使用return语句同时返回多个值,如果return后面跟的是多个返回值,那么python会隐式的将这多个返回值封装成一个元祖,作为一个返回值返回给调用者。

作用域:
函数嵌套:
在一个函数中定义另外一个函数,这就是函数嵌套,在函数嵌套中,函数是有可见范围的,这就是作用域的概念,内部函数不能在外部直接调用,否则会抛NameError异常,因为内层函数对外部而言是不可见的。
全局作用域:在整个程序运行环境中都可见,全局作用域中的变量称为全局变量。
局部作用域(本地作用域):仅在函数、类的内部可见,外部不可见,局部作用域中的变量称为局部变量,局部变量的使用范围不能超过其所在的局部作用域。
在函数的嵌套结构中:
外层函数的局部作用域中的局部变量对内层函数而言是可见的。
如果内层函数的局部作用域中定义了一个和外层函数作用域中同名的局部变量的话,内层函数中的局部变量并不会覆盖外层函数中的同名局部变量,因为它们是不同作用域中的变量,作用域相互隔离,不会相互干扰。

自由变量:如果内层函数中引用了外层函数中的某个局部变量,那么这个变量就称为自由变量。
闭包:内层函数引用到了外层函数的自由变量,就形成了闭包。

global关键字将函数内的变量声明为全局作用域中定义的变量,前提条件是全局作用域中必须要事先有该变量的定义,否则会抛NameError异常。
nonlocal关键字将变量标记为不在本地作用域定义,而在上级的某一级局部作用域中定义,但不能是全局作用域中定义。

    python会把函数的所有位置形参的默认值封装成一个元组赋值给__defaults__属性。
    函数的所有keyword-only形参的默认值封装成一个字典赋值给__kwdefaults__属性。

迭代函数:
函数递归的定义如下:
函数直接或者间接地调用自身就是递归
递归需要有边界条件、递归前进段、递归返回段
递归一定要有边界条件,否则就会出现无限递归的情况,导致栈溢出的严重后果。
当边界条件不满足的时候,递归前进
当边界条件满足的时候,递归返回递归存在的意义就是循环,单个函数本身不会循环,但是函数调用函数自身就形成了循环,边界条件就相当于退出循环的条件。将上一次的计算结果直接作为函数的形参传入,实现数据的接棒。递归和传统的循环结构相比,性能普遍低下,并且递归是有深度限制的。

递归存在的意义就是循环,单个函数本身不会循环,但是函数调用函数自身就形成了循环,边界条件就相当于退出循环的条件。将上一次的计算结果直接作为函数的形参传入,实现数据的接棒。递归和传统的循环结构相比,性能普遍低下,并且递归是有深度限制的。
匿名函数:
lambda表达式的语法格式如下:
lambda 参数列表:表达式

语法解释如下:
使用lambda关键字来定义匿名函数,参数列表不需要小括号,使用冒号来分隔参数列表和表达式
不需要使用return关键字,表达式的值就是匿名函数的返回值
lambda表达式(匿名函数)只能写在一行上,被称为单行函数
lambda表达式的常规使用如下:
print((lambda :0)())
print((lambda x, y=3: x + y)(5))
print((lambda x, y=3: x + y)(5, 6))
print((lambda x, , y=30: x + y)(5))
print((lambda x,
, y=30: x + y)(5, y=10))
print((lambda args: (x for x in args))(range(5)))
print((lambda args: [x+1 for x in args])(range(5)))
print((lambda args: {x+2 for x in args})(range(5)))

生成器函数:
使用yield关键字创建一个生成器函数
生成器函数总结:
包括yield语句的生成器函数生成生成器对象时,生成器函数的函数体不会立即执行
next(generator)会从函数的当前位置向后执行到之后碰到的第一个yield语句,会弹出yield表达式的返回值,并暂停函数执行
再次调用next函数,和上一条一样的处理过程
没有多余的yield语句能够被执行,继续调用next函数,会抛出StopIteration异常
yield from iterable
等价于:
for item in iterable:yield item形式的语法糖