当前位置: 首页 > news >正文

Python基础③-函数篇

1.序言

本篇文章从基础的函数参数分类、实参传递方式和函数返回值的特性,到进制转换等实用技巧,再到函数的高级特性如嵌套定义、作为返回值和参数传递等等方面展开。此外,还会介绍allany函数的使用,以及作用域、闭包和装饰器等重要概念。

无论你是 Python 编程的初学者,还是希望进一步提升编程技能的开发者,相信通过本文的学习,你将对 Python 函数有更深入的理解和掌握。

2.函数参数

2.1 参数分类及概念

  1. 形参(形式参数):在函数定义时,用于接收外部传入信息的变量,是函数定义时准备的“占位符”。例如:
def func(a, b):  # a、b 就是形参,定义时用来接收后续调用传入的值print(a + b)
  1. 实参(实际参数):在调用函数时,实际传递给函数的信息,是实实在在的值或变量。比如:
func(3, 5)  # 3、5 是实参,调用时传递给形参 a、b

在这里插入图片描述

2.2 实参传递方式

  1. 位置参数:按照形参定义的位置顺序传递参数。
def func(a, b):print(f"a: {a}, b: {b}")
func(10, 20)  # 10 传给 a,20 传给 b,按位置对应

在这里插入图片描述

  1. 关键字参数:通过参数名来传递参数,无需严格遵循位置顺序

但位置参数要放在关键字参数前面,否则会报错,注意这里是有顺序之分的。

def func(a, b):print(f"a: {a}, b: {b}")
func(b=20, a=10)  # 通过指定参数名,10 传给 a,20 传给 b 
# 错误示例(位置参数放关键字参数后面)
# func(b=20, 10)  # 这样会报错,位置参数不能在关键字参数之后

在这里插入图片描述

  1. 混合参数:位置参数和关键字参数一起使用,位置参数要放在前面。
def func(a, b, c):print(f"a: {a}, b: {b}, c: {c}")
func(1, c=3, b=2)  # 1 是位置参数传给 a,b=2、c=3 是关键字参数,符合位置参数在前规则

在这里插入图片描述

2.3 动态参数

  1. *args:用于接收任意数量的位置参数,会将传入的位置参数打包成一个元组。
def func(*args):print(args)
func(1, 2, 3, 4)  # 输出:(1, 2, 3, 4),接收到的多个位置参数被打包成元组

在这里插入图片描述

相当于说不限制你定义的这个函数要接收多少参数了。

  1. **kwargs:用于接收任意数量的关键字参数,会将传入的关键字参数打包成一个字典。
def func(**kwargs):print(kwargs)
func(name="张三", age=20)  # 输出:{'name': '张三', 'age': 20},关键字参数被打包成字典

在这里插入图片描述

但这里在调用函数时必须要有指定,不可以直接写数值。

  1. 参数顺序:在函数定义中,参数顺序需遵循:位置参数 -> *args -> 默认参数 -> **kwargs ,否则会报错。示例:
def func(a, b, *args, c="哈哈", **kwargs):print(a, b, args, c, kwargs)
func(1, 2, 3, 4, c="呵呵", hello=456, haha_lou=654)
# 输出:1 2 (3, 4) 呵呵 {'hello': 456, 'haha_lou': 654}
# 解释:a=1(位置参数), b=2(位置参数), args=(3,4)(动态接收多余位置参数), 
# c="呵呵"(传入值覆盖默认值), kwargs 接收剩余关键字参数

在这里插入图片描述

这里需要注意,如果你想要直接更改c的值,最简单省事的方法实际上就是直接令c=**这种形式,

如果你按照顺序,比如说

def func(a, b, c="哈哈", *args **kwargs):
func(1, 2, 3, 4)

那你的c的数值运行后就变成3了。

3.函数返回值(return

3.1 基本概念

函数执行完毕后,会给调用方一个结果,这个结果就是返回值,由 return 语句控制。

3.2return特性

  1. 函数中只要执行到 return,函数会立即停止执行,return 后续的代码不再执行。
def func():print("执行到 return 前")returnprint("执行到 return 后,不会执行")
func()
# 输出:执行到 return 前

在这里插入图片描述

  1. 函数内没有 return 时,外界调用函数收到的返回值是 None
def func():print("函数内无 return")
result = func()
print(result)  # 输出:函数内无 return   None

在这里插入图片描述

  1. return 不同用法:

    只写 return,后面不跟数据,外界收到 None(一般用于提前结束函数)。

def func():return
result = func()
print(result)  # 输出:None

在这里插入图片描述

return 后跟一个值,外界能收到这个数据。

def func():return 10
result = func()
print(result)  # 输出:10

在这里插入图片描述

return 后跟多个值,外界收到的是元组,包含所有返回值。

def func():return 1, 2, 3
result = func()
print(result)  # 输出:(1, 2, 3)

在这里插入图片描述

在掌握了函数参数和返回值这些函数基础内容之后,我们换个角度,来了解一些 Python 中与数据表示相关的实用知识——进制转换。

它虽然和函数没有直接关联,但同样是 Python 编程基础篇里面需要认识到的知识点。

4.进制转换相关

4.1 十进制转其他进制

  1. 转二进制:使用 bin() 函数,将十进制数转成二进制字符串表示。
a = 18  # 十进制数
print(bin(a))  # 输出:0b10010  ,0b 是二进制标识
  1. 转八进制:使用 oct() 函数,将十进制数转成八进制字符串表示。
a = 18
print(oct(a))  # 输出:0o22  ,0o 是八进制标识
  1. 转十六进制:使用 hex() 函数,将十进制数转成十六进制字符串表示。
a = 18
print(hex(a))  # 输出:0x12  ,0x 是十六进制标识

在这里插入图片描述

4.2 其他进制转十进制

对于二进制、八进制、十六进制数转十进制,使用 int() 函数,指定 base 参数(二进制 base=2,八进制 base=8,十六进制 base=16 )。

# 二进制转十进制
a = 0b10010
print(int(a))  # 输出:18  ,将二进制数转成十进制
# 八进制转十进制
b = 0o22
print(int(b))  # 输出:18  ,将八进制数转成十进制
# 十六进制转十进制
c = 0x12
print(int(c))  # 输出:18  ,将十六进制数转成十进制

在这里插入图片描述

了解完进制转换这种数据处理技巧后,让我们再次聚焦到函数上,

深入探索Python函数的高级特性,这些特性会让你的函数编程更加灵活和强大。

5. 函数高级特性

5.1 函数嵌套定义

函数内部可以再定义函数,内层函数可访问外层函数的变量,外层函数可返回内层函数供外部使用,用于封装逻辑、实现闭包等场景。

def outer():message = "外层函数变量"def inner():# 访问外层函数的变量print(message)  return inner  # 返回内层函数# 调用外层函数,得到内层函数
inner_func = outer()  
inner_func()  # 输出:外层函数变量

在这里插入图片描述

5.2 函数作为返回值

函数执行后可返回另一个函数,让返回的函数后续按需调用,常用于根据条件动态生成函数逻辑。

def maker(flag):def add(a, b):return a + bdef sub(a, b):return a - b# 根据 flag 返回不同函数return add if flag else sub  # 获取加法函数
add_func = maker(True)  
result = add_func(3, 5)
print(result)  # 输出:8# 获取减法函数
sub_func = maker(False)  
result = sub_func(8, 3)
print(result)  # 输出:5

在这里插入图片描述

5.3 函数作为参数传递

函数可以当作参数传给另一个函数,让被调用函数灵活执行不同逻辑,是回调函数、高阶函数的基础。

def target():print("我是目标函数")def caller(func):# 执行传入的函数func()  caller(target)  # 输出:我是目标函数

在这里插入图片描述

你看这里,target作为caller函数的输入,然而定义的caller函数会将传进去的参数当函数去执行,

那种样子就相当于执行target函数,就打印我是目标函数出来了。

5.4 函数名的本质

函数名本质是变量,存储函数对象在内存中的地址,可赋值、传递,也能查看其指向的内存地址。

def func():print("函数执行")# 查看函数名对应的内存地址
print(func)  
# 输出类似:<function func at 0x0000023...> # 赋值给新变量,新变量也指向该函数
new_func = func  
new_func()  # 输出:函数执行

在这里插入图片描述

5.5 多层函数嵌套执行流程

多层嵌套函数按“从外到内定义,从内到外执行”的顺序,理清调用层级和变量作用域是关键。

def func1():print(123)def func2():print(456)def func3():print(789)print(1)func3()print(2)func2()print(3)func1()  
# 执行顺序与输出:
# 123(func1 外层执行)
# 456(func2 中层执行)
# 789(func3 内层执行)
# 1(func3 内层执行)
# 2(func3 执行完,回到 func2 中层执行)
# 3(func2 执行完,回到 func1 外层执行)

在这里插入图片描述

6. allany函数

6.1 all函数

主要用于接收可迭代对象(列表、元组等),判断所有元素是否都为真(非 0、非空、非 None 等),全为真返回 True,否则返回 False

# 列表元素全为真
list1 = [True, 1, "hello"]
print(all(list1))  # 输出:True  # 列表含假值(0 视为假)
list2 = [1, 0, "world"]
print(all(list2))  # 输出:False  # 空可迭代对象,返回 True(无元素可视为“所有元素都满足”)
list3 = []
print(all(list3))  # 输出:True  

在这里插入图片描述

你可以把这个函数当成一个and来看待。

6.2 any函数

主要作用是接收可迭代对象,判断是否至少有一个元素为真,有一个及以上为真返回 True,全为假返回 False

# 列表至少一个真(True 为真)
list1 = [False, 0, True]
print(any(list1))  # 输出:True  # 列表全为假(0、空字符串、False 都为假)
list2 = [0, "", False]
print(any(list2))  # 输出:False  # 空可迭代对象,返回 False(无元素可视为“没有元素满足”)
list3 = []
print(any(list3))  # 输出:False  

在这里插入图片描述

6.3 对比与适用场景

函数判定逻辑典型场景
all所有元素为真才返回 True校验一组条件是否全部满足
any至少一个元素为真返回 True校验一组条件是否有任意满足

我们已经学习了用于判断可迭代对象元素真假性的 allany 函数,

接下来要探讨的是 Python 中变量作用域以及相关关键字,这对于理解函数内外变量的使用和修改规则还是很重要的。

7.作用域与关键字

7.1 作用域基础

Python 中变量有局部作用域(函数内)和全局作用域(函数外)。默认情况下,

函数内定义的变量是局部变量,只能在函数内使用。

函数外定义的变量是全局变量,可在整个脚本中使用。

7.2 global:引入全局变量

作用则是在局部作用域(函数内) 中,明确声明使用全局变量,修改后会影响全局作用域的变量值。

# 全局变量
a = 10  def func():# 声明使用全局变量 aglobal a  # 修改全局变量a = 20  print(f"函数内 a 的值: {a}")func()
# 全局变量已被修改
print(f"函数外 a 的值: {a}")  

输出

在这里插入图片描述

7.3 nonlocal:引入外层局部变量

作用是在嵌套函数中,从外层(非全局)的局部作用域引入变量,修改后会影响外层局部作用域的变量值。

def func():# 外层函数的局部变量a = 10  def func2():# 引入外层函数的局部变量 anonlocal a  # 修改外层函数的局部变量a = 20  print(f"内层函数 func2 中 a 的值: {a}")func2()# 外层函数的变量已被修改print(f"外层函数 func 中 a 的值: {a}")  func()

输出

在这里插入图片描述

掌握了变量作用域和 globalnonlocal 关键字后,我们可以基于这些知识来理解 Python 中一个非常有用的概念——闭包。

8.闭包

就是嵌套函数中,内层函数引用了外层函数的变量(非全局),并且外层函数返回内层函数,这样的结构称为闭包

主要用处在于让变量常驻内存,即使外层函数执行完毕,内层函数仍可访问外层函数的变量,还可以有效防止不经意间全局变量的数值被更改。

def func():# 外层函数的变量a = 10  def inner():# 引入外层变量(非全局)nonlocal a  a += 1  return a# 返回内层函数,形成闭包return inner  # 获取闭包函数
closure = func()  
# 每次调用闭包,操作的是外层函数的变量 a
print(closure())  # 输出: 11
print(closure())  # 输出: 12

在这里插入图片描述

说到底,闭包就是为我们提供了一种让变量常驻内存、保存状态的方法,

基于闭包的思想,我们可以进一步了解 Python 中的装饰器。

装饰器本质上是一种特殊的闭包,它能在不修改原函数代码的情况下为函数添加额外功能。

9.装饰器

9.1 定义

本质是一个闭包,用于在不修改原函数代码的前提下,为函数添加额外功能

目前主要的用途有以下两个,

  • 解耦:原函数只需关注核心逻辑,额外功能由装饰器处理。
  • 复用:装饰器可被多个函数共享,避免重复代码。

9.2 基础装饰器结构

# 装饰器函数,fn 是被装饰的目标函数
def wrapper(fn):  def inner():# 目标函数执行前的逻辑(如日志)print("在目标函数执行之前....")  # 执行目标函数fn()  # 目标函数执行后的逻辑(如统计)print("在目标函数执行之后....")  # 返回内层函数,替代原函数return inner  

9.3 装饰器用法与示例

场景:给游戏函数添加“开挂”和“关闭外挂”的日志
# 装饰器:给游戏函数添加额外逻辑
def guanjia(game):  def inner():print("打开游戏加速器")# 执行原游戏函数game()  print("关闭游戏加速器")return inner# 原函数 1
def play_dnf():  print("dnf游戏进程ing!")# 原函数 2
def play_lol():  print("lol游戏进程ing!")# 用装饰器增强函数
play_dnf = guanjia(play_dnf)  
play_lol = guanjia(play_lol)  # 调用增强后的函数
play_dnf()  
play_lol()  

输出

在这里插入图片描述

语法糖简化:@ 符号

装饰器还可通过 @ 语法糖简化,效果与手动赋值一致:

def guanjia(game):def inner():print("打开游戏加速器")game()print("关闭游戏加速器")return inner# 语法糖:直接用 @ 装饰函数
@guanjia  
def play_dnf():print("dnf游戏进程ing!")@guanjia  
def play_lol():print("lol游戏进程ing!")# 直接调用,效果相同
play_dnf()  
play_lol()  

9.4 装饰器的典型应用场景

一般常用于以下三种场景,记录函数调用时间、参数等日志记录;调用函数前检查用户是否登录的权限校验;统计函数执行耗时的性能统计

9.5 知识关联总结

知识点核心作用典型场景
global局部作用域中操作全局变量全局配置修改
nonlocal嵌套函数中操作外层局部变量闭包变量修改
闭包让变量常驻内存,实现数据持久化计数器、状态保持
装饰器不修改原函数,动态添加功能日志、权限、性能统计

10.小结

本文系统介绍了Python函数的相关知识。从基础层面出发,详细讲解了函数参数的分类、实参传递方式以及函数返回值的特性,同时也介绍了进制转换的方法。

在高级特性部分,探讨了函数的嵌套定义、作为返回值和参数传递等用法,作用域、闭包和装饰器等概念的讲解并给出相应程序示例,

通过本文的学习,希望读者能够对Python函数有一个全面的认识,在实际编程中更加熟练地运用。

http://www.dtcms.com/a/284617.html

相关文章:

  • 【git 如何查看本地分支与远程分支之间的差异】
  • Solr7升级Solr8全攻略:从Core重命名到IK分词兼容,零业务中断实战指南
  • GLM(General Language Model,通用语言模型)
  • CCLink IE转ModbusTCP网关配置无纸记录器(中篇)
  • Python应用进阶DAY7--面向对象编程基本特性和super函数
  • 2025解锁“分身术”???
  • 微信小程序151~160
  • 针对教育行业的网络安全方案有哪些
  • 手机兼容测试服务提供商对比分析:如何选择最合适的测试平台
  • 输尿管下段积水预测与手术决策支持技术方案
  • 订货系统多角色支持核心实战指南
  • LLMFactory导出的Merge模型导入ollama
  • 从平面到时空:地图故事的时空叙事与沉浸式阅读
  • 征程 6 UCP 任务优先级 抢占简介与实操
  • Qt5 与 Qt6 详细对比
  • .NET 8.0 使用 WebSocket
  • 24、鸿蒙Harmony Next开发:不依赖UI组件的全局自定义弹出框 (openCustomDialog)
  • 趋势分析:从数据波动中读懂产品的 “健康信号”
  • 使用 docker 安装 openldap
  • JMeter在Linux命令行模式下执行的核心参数及使用场景,结合官方文档与实战经验整理,便于快速查阅
  • 【软件开发】Copilot 编码插件
  • demComponent
  • Java常用命令汇总
  • 中兴B860AV5.1-M2_S905L3SB最新完美版线刷包 解决指示灯异常问题
  • 微服务网站开发学习路线与RuoYi-Cloud实战指南
  • Spring Boot 监控:AOP vs Filter vs Java Agent
  • BI 数据可视化平台建设(3)—首页性能提升实践
  • ThinkPHP8 Windows开发全流程:从搭建到上线
  • 【Android代码】绘本翻页时通过AI识别,自动通过手机/pad朗读绘本
  • MTK平台--如何查询手机连接的TX速率和带宽