函数
什么是函数
函数是一段可重复使用的代码块,用于执行特定的任务
函数的作用
- 提高代码的可重用性: 使用函数可以将代码块组织成更小的可重用模块,减少代码的冗余。
- 提高代码的可读性: 使用函数可以使代码更加简洁和易于理解,也更容易进行调试和维护。
- 提高代码的模块化: 使用函数可以将程序分解成更小的模块,每个模块都可以处理特定的任务,这样程序的组织结构更加清晰。
- 提高代码的可扩展性: 使用函数可以使程序更易于扩展和修改,因为函数可以独立地编写和测试,而不会影响程序的其他部分。
函数就是设计一个技能需要时自己调用,调用的方法本质上是个函数 。两者的区别是使用的方式不一样。
函数写法
1 | # 用def定义一个函数 |
函数的形参和实参
- 不传值给函数可以不带形参和实参
- 形参名字可以随意定义
- 形参和实参数量必须一致
- 实参对应形参
- 形参可以赋默认参数 没有传就以默认参数 传了就以实参
- 实参也可以指定形参
- 通过*形参名可以获取所有实参,通过索引获取对应实参
1 | # 用def定义一个函数 |
案例
1 | # 形参的默认参数 |
1 | # 通过*形参名可以获取所有实参 |
内置函数
Python自带的一些函数,我们可以直接拿来使用
1 | # 打印 |
字符串、列表、元组、集合 的增删改查的方法 数值类型,详细内容与调用方法跳转查阅
函数的说明文档
- 给函数中的代码做解释说明
- 让其他程序员知道函数的作用
- 函数里的注释
如何写说明文档
- 三引号包裹
1 | def add(a, b): |
1 | def add(a, b): |
函数的嵌套
在函数内部调用其它函数
尽量不要嵌套太多层,不然就是屎山了
1 | # 1.定义一个函数a |
函数的作用域
Python 中的函数作用域分为两种: 全局作用域和局部作用域
- 全局作用域指的是在模块(文件)中定义的变量和函数,可以在模块的任何地方被访问和使用
- 局部作用域指的是在函数内部定义的变量和函数,只能在该函数内部被访问和使用
1 | # 变量a 全局作用域 |
global 关键字
使用 global
关键字 可以在函数内部声明变量为全局变量
1 | # 定义两个变量 textA textB |
闭包 Closure
内部函数使用了外部函数的变量
1 | def func(): # 外部函数 |
好处
好处: 保存局部变量的状态 我们可以将相关的功能和数据绑定在一起,而不用担心数据被其他代码修改。
应用:想保存数据状态和不被污染 我们就可以使用闭包。很多框架底层 保存数据都是用的闭包
1 | def func(): |
- 因此可以发现通过闭包,可以使得数据状态得到存储,例如存储累加的结果
- 且闭包的数据无法通过全局变量进行修改,保证数据完整性,因为是由子函数进行累加的
- 需要保存数据状态的时候就需要使用闭包
- 使用场景例如 第三方库 能够保存数据状态
信息
1 | a = "Global" |
在 Python 中,变量的使用和修改遵循不同的规则,特别是在涉及嵌套函数时。这是因为 Python 对变量的查找(读取)和赋值(修改)有不同的作用域规则。
- 读取变量:当代码尝试读取一个变量的值时(如在
print(a)
中),Python 会遵循作用域查找规则。这意味着它会首先在当前函数的局部作用域查找该变量。如果在当前作用域找不到,它会在外围作用域中查找,一直查找到全局作用域,最后是内置作用域。这就是为什么在上面的例子中,即使没有使用nonlocal
关键字,fun_in
也能访问fun_out
中定义的a
变量。 - 修改变量:当尝试修改一个变量的值时,Python 的默认行为是在当前作用域创建或更新该变量。如果在一个嵌套的函数中不加声明地修改一个变量,Python 会认为这是一个新的局部变量,而不是一个外围作用域中的变量。
- 使用
nonlocal
关键字:当想在一个嵌套函数中修改外围函数的局部变量时,需要使用nonlocal
关键字。这样做可以告诉 Python 想修改的是外围作用域中的变量,而不是创建一个新的局部变量。 - 全局变量:如果想在一个函数中修改全局变量,而不是创建同名的局部变量,需要使用
global
关键字。
- 使用
这种区分是为了避免意外修改外围作用域中的变量,这可能会导致难以追踪的错误。通过要求显式声明 nonlocal
或 global
,Python 增强了代码的可读性和可维护性。
闭包(Closure)和嵌套函数(Nested Functions)的区别
闭包(Closure)
在编程中,闭包是指那些能够访问自己外部作用域中变量的函数。一个闭包至少由两部分组成:一个函数以及该函数引用的外部变量。Python 中闭包的一个关键特征是它保持了对其外部变量的引用,即使在外部函数已经结束执行之后。
在代码中,fun_in
是一个闭包,因为它是在 fun_out
内部定义的,并且引用了 fun_out
作用域内的变量 a
。当 fun_out
被调用并返回 fun_in
时,尽管 fun_out
的执行已经结束,fun_in
依然保留了对变量 a
的引用。这样,即使是在 fun_out
执行完毕之后,fun_in
仍然可以访问并打印变量 a
的值。
嵌套函数(Nested Functions)
嵌套函数是在另一个函数内部定义的函数。虽然所有闭包都是嵌套函数,但并非所有嵌套函数都是闭包。一个嵌套函数只有在引用了其外部函数的变量时,它才构成一个闭包。
总结
fun_in
作为一个闭包,即使在其外部函数 fun_out
执行完毕后,仍然可以访问并使用 fun_out
作用域中的变量 a
。
匿名函数
匿名函数,通常在 Python 中通过 lambda
关键字来定义,是一种没有显式函数名的简短函数。它们在语法上是简洁的,通常用于编写小的、一次性的、不需要单独定义函数名的函数。
匿名函数是一个可以定义并立即使用的简洁函数形式。在 Python 中,匿名函数使用 lambda
关键字创建,其基本语法是:
1 | lambda 参数列表: 表达式 |
这种函数通常用于简单的操作,比如简单的数学运算、字符串操作等。由于它们只是单个表达式,所以不能像普通函数那样执行复杂的操作
1 | # lambda : 8 创建了一个匿名函数,这个函数没有参数,并且总是返回数字 8 |
匿名函数的作用
匿名函数的主要作用是简化代码,尤其是在需要小的函数作为参数时,例如在排序操作、高阶函数(如 map()
、filter()
)或任何需要函数对象的地方。由于它们不需要定义传统的函数结构,因此可以在代码中快速定义和使用。
何时使用匿名函数
匿名函数通常在以下情况下使用:
- 简单的功能:当函数的功能非常简单,只需要一行代码就可以实现时,使用匿名函数是一个很好的选择。
- 一次性使用:当有一个不会在代码的其他地方复用的小函数时,使用匿名函数可以减少不必要的函数定义。
- 作为参数传递:当一个函数接受另一个函数作为参数时,如果这个参数函数非常简短,使用匿名函数可以使代码更加清晰。常见的例子包括
map()
、filter()
和sorted()
等函数。
QA
问:
函数通过function关键字定义吗?
答:
这个说法是错误的。在Python中,函数是通过 def
关键字来定义的,而不是 function
。例如:def my_function():
。
问:
调用函数使用函数名即可吗?
答:
这个说法是正确的。在Python中,函数通过其名称来调用,可能跟随一对圆括号和必要的参数。例如,如果有一个名为 my_function
的函数,可以通过 my_function()
来调用它。
问:
函数必须要有返回值return
答:
这个说法是错误的。函数不一定需要有 return
语句。如果没有 return
语句,函数默认返回 None
。return
语句用于从函数中返回一个值。
问:
函数里面直接定义的变量外部不能访问
答:
这个说法是正确的,但需要一些澄清。在Python中,函数内部定义的变量是局部的,意味着它们只在函数内部可见。外部代码不能直接访问函数内部的局部变量。然而,如果需要在外部访问这些变量的值,可以通过函数返回这些值来实现。
- 标题: 函数
- 作者: Yiuhang Chan
- 创建于 : 2018-08-12 16:43:23
- 更新于 : 2024-02-28 18:49:04
- 链接: https://www.yiuhangblog.com/2018/08/12/20180812函数/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。