1、函数 function

定义

用于封装一个特定的功能,表示一个功能或者行为。

函数是可以重复执行的语句块, 可以重复调用


作用

提高代码的可重用性和可维护性(代码层次结构更清晰)。


定义函数

  • 语法:

def 函数名(形式参数):

     函数体

  • 说明:

def 关键字:全称是define,意为”定义”。

函数名:对函数体中语句的描述,规则与变量名相同。

形式参数:方法定义者要求调用者提供的信息。

函数体:完成该功能的语句。

  • 函数的第一行语句建议使用文档字符串描述函数的功能与参数。

2、调用函数

语法:函数名(实际参数)

说明:根据形参传递内容。

3、返回值

  • 定义:

方法定义者告诉调用者的结果。

  • 语法:

return 数据 

  • 说明:

return后没有语句,相当于返回 None。

函数体没有return,相当于返回None。

4、可变/不可变类型在传参时的区别

  • 不可变类型参数有:

数值型(整数,浮点数,复数)

布尔值bool

None 空值

字符串str

元组tuple

固定集合frozenset


  • 可变类型参数有:

列表 list

字典 dict

集合 set


  • 传参说明:

不可变类型的数据传参时,函数内部不会改变原数据的值。

可变类型的数据传参时,函数内部可以改变原数据。


代码示例一:

l1 = ["123"] l2 = ["abc"] def fun(p1, p2): # 切片赋值会修改原列表 p1[:] = ["1"] # 浅拷贝,修改拷贝后的对象不影响原对象 temp = p2[:] temp = ["a"] fun(l1, l2) print(l1) # ['1'] print(l2) # ['abc']


5、实参传递方式argument

位置传参

定义:实参与形参的位置依次对应。


序列传参

定义:实参用*将序列拆解后与形参的位置依次对应。

def func(a, b, c): print(a) print(b) print(c) l = [10, 20, 30] s = "abcd" func(*l) # *可以解开列表、元组、字符串等序列 func(*s) # 报错,解开后数量对不上TypeError: func() takes 3 positional arguments but 4 were given

关键字传参

定义:实参根据形参的名字进行对应。


字典关键字传参

定义:实参用**将字典拆解后与形参的名字进行对应。

作用:配合形参的缺省参数,可以使调用者随意传参。

def fun(a, b, c): print(a) print(b) print(c) d = {"a": 10, "b": 20, "c": 30} fun(**d) # 字典的key一定要跟形参是一样的否则报错 # 10 # 20 # 30


6、形参定义方式parameter

缺省(默认)参数

语法:

def 函数名(形参名1=默认实参1, 形参名2=默认实参2, ...):

      函数体

说明:

缺省参数必须自右至左依次存在,如果一个参数有缺省参数,则其右侧的所有参数都必须有缺省参数。

缺省参数可以有0个或多个,甚至全部都有缺省参数。


位置形参

语法:

def 函数名(形参名1, 形参名2, ...):

函数体


星号元组形参

语法:

def 函数名(*元组形参名):

  函数体

作用:

收集多余的位置传参。

说明:

一般命名为'args'

形参列表中最多只能有一个


命名关键字形参

语法:

def 函数名(*, 命名关键字形参1, 命名关键字形参2, ...):

函数体

def 函数名(*args, 命名关键字形参1, 命名关键字形参2, ...):
            函数体

作用:

强制实参使用关键字传参

def func(*args, p1, p2): print(*args) print(p1) print(p2) func(1, 11, 1, 1, p1=1, p2=1000) # 因为前面的*args 所以后面的参数传参时必须一样,强制命名 func(1, 11, 1, 1, p0=1, p2=1000) # TypeError: func() got an unexpected keyword argument 'p0'


双星号字典形参

语法:

def 函数名(**字典形参名):

函数体

作用:

收集多余的关键字传参

说明:

一般命名为'kwargs'

形参列表中最多只能有一个

def func(**kwargs): print(kwargs) func(a=10) # {'a': 10} func(a=1, b=2) # {'a': 1, 'b': 2}


参数自左至右的顺序

位置形参 --> 星号元组形参 --> 命名关键字形参 --> 双星号字典形参

7、作用域LEGB

作用域:变量起作用的范围。


Local局部作用域:函数内部。

Enclosing  外部嵌套作用域 :函数嵌套。

Global全局作用域:模块(.py文件)内部。

Builtin内置模块作用域:builtins.py文件。

8、变量名的查找规则

由内到外:L -> E -> G -> B

在访问变量时,先查找本地变量,然后是包裹此函数外部的函数内部的变量,之后是全局变量,最后是内置变量。

# global全局作用域 当前模块 a = 100 def change(): a = 2 # 局部作用域,当前函数内部,inner_func函数的外部 def inner_func(): # 局部作用域 a = 1 print(a) inner_func() print(a) change() # 1 # 2


9、局部变量

定义在函数内部的变量(形参也是局部变量)

只能在函数内部使用

调用函数时才被创建,函数结束后自动销毁

10、全局变量

定义在函数外部,模块内部的变量。

在整个模块(py文件)范围内访问(但函数内不能将其直接赋值)。

11、global 语句

作用:

在函数内部修改全局变量。

在函数内部定义全局变量(全局声明)。

语法:

global 变量1, 变量2, …


说明

在函数内直接为全局变量赋值,视为创建新的局部变量。

不能先声明局部的变量,再用global声明为全局变量。

12、nonlocal 语句

作用:

在内层函数修改外层嵌套函数内的变量


语法

nonlocal 变量名1,变量名2, ...

说明

在被嵌套的内函数中进行使用

def func1(): a = 10 def func2(): nonlocal a a += 1 print(a) func2() print(a) func1() # 11 11


13、locals()

locals()

会收集当前所有的局部变量  保存为字典