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

Python 函数完全指南:定义与调用

目录

1. 什么是函数?

2. 函数的定义

2.1 基本语法

2.2 带参数的函数

2.3 带返回值的函数

2.4 空函数(占位)

3. 函数的调用

4. 参数类型详解

4.1 位置参数(必须参数)

4.3 关键字参数

4.4 可变长度参数

4.5 参数组合顺序

5. 返回值详解

5.1 单个返回值

5.2 多个返回值(本质是返回元组)

5.3 return 语句省略时返回 None

5.4 return 提前退出函数

6. 作用域

6.1 局部变量与全局变量

6.2 nonlocal 关键字(用于嵌套函数)

7. 函数也是对象

8. 匿名函数(lambda)

9. 递归函数

10. 类型注解(Type Hints)

11. 常见内置函数示例

12.常见陷阱与最佳实践


在编程中,我们经常需要重复执行某段代码。如果每次都复制粘贴,不仅代码冗长,而且修改起来非常麻烦。函数就是解决这个问题的利器:它将一段具有独立功能的代码打包成一个“积木块”,需要时只需“调用”即可。

1. 什么是函数?

函数是一段可重复使用的代码块,它接收输入(参数),进行处理,并可能返回输出(返回值)。函数可以帮你:

  • 避免重复:同样的逻辑只需写一次。

  • 模块化:将复杂程序拆分成小功能块。

  • 易维护:修改函数内部实现,所有调用处自动生效。

Python 内置了很多函数(如print()len()),你也可以自定义函数。

2. 函数的定义

2.1 基本语法

使用def关键字定义函数,后面跟函数名、括号()和冒号:,函数体缩进。

def function_name(parameters):
"""可选的文档字符串"""
函数体代码
return 返回值 # 可选

eg

def greet(): """打印欢迎信息""" print("Hello, welcome to Python!") # 调用函数 greet()
  • def greet():def是定义函数的关键字,greet是函数名,空括号表示该函数不接受任何参数,冒号表示函数体开始。

  • """打印欢迎信息""":这是一个文档字符串(docstring),用三个双引号包围。它是对函数功能的说明,可以通过help(greet)greet.__doc__查看。虽然不是必需的,但强烈建议添加。

  • print("Hello, welcome to Python!"):这是函数体,缩进表示属于函数的一部分。当函数被调用时,这一行代码会被执行。

  • greet():调用函数,执行函数体内的代码。

2.2 带参数的函数

def greet_person(name): """向指定的人打招呼""" print(f"Hello, {name}!") greet_person("Alice") # Hello, Alice!
  • def greet_person(name)::定义了一个形参name,它将在函数内部作为变量使用。

  • print(f"Hello, {name}!"):函数体内使用了name变量,它的值由调用时传入。

  • greet_person("Alice"):调用时传入实参"Alice",它会被赋值给形参name,因此函数体内输出Hello, Alice!

2.3 带返回值的函数

使用return语句返回结果。

def add(a, b): """返回两个数的和""" result = a + b return result sum_val = add(3, 5) # 返回 8 print(sum_val)

代码解析

  • def add(a, b)::定义两个形参ab

  • result = a + b:计算两个参数的和,赋值给局部变量result

  • return result:将result的值返回给调用者。函数执行到return语句时会立即结束,并将返回值传递给调用方。

  • sum_val = add(3, 5):调用add函数,实参35分别传给ab,函数返回8,然后赋值给变量sum_val

  • print(sum_val):输出8

2.4 空函数(占位)

如果函数体还未实现,可以用pass占位。

def not_ready(): pass # 稍后实现

代码解析

  • def not_ready()::定义函数。

  • pass:是一个空语句,什么都不做。语法上需要一个语句,但逻辑上还未实现,用pass避免语法错误。


3. 函数的调用

调用函数就是使用函数名加上括号和实际参数。

# 定义 def multiply(x, y): return x * y # 调用 result = multiply(4, 5) print(result) # 20

代码解析

  • def multiply(x, y)::定义乘法函数。

  • return x * y:返回两数乘积。

  • result = multiply(4, 5):调用函数,实参4对应x5对应y,返回值20存入result

  • print(result):输出20

调用时的细节

  • 函数名后面必须跟括号,即使没有参数也要写()

  • 实参会按照形参的位置一一对应(位置参数)。

  • 调用时传递的实参个数必须与形参个数匹配(除非有默认参数)。

4. 参数类型详解

4.1 位置参数(必须参数)

最普通的形式,调用时按顺序传递。

def greet_with_default(name, greeting="Hello"): print(f"{greeting}, {name}!") greet_with_default("Alice") # Hello, Alice! greet_with_default("Bob", "Hi") # Hi, Bob!

代码解析

  • greeting="Hello":为greeting参数指定默认值"Hello"。调用时若不提供第二个参数,则使用默认值。

  • greet_with_default("Alice"):只传一个参数,greeting使用默认值"Hello",输出Hello, Alice!

  • greet_with_default("Bob", "Hi"):传入两个参数,greeting被覆盖为"Hi",输出Hi, Bob!

注意:默认参数必须放在非默认参数之后。

# 错误写法 def wrong(a=1, b): # SyntaxError pass

陷阱:默认参数的值只在函数定义时计算一次,因此不能使用可变对象作为默认值(如列表)。

# 不推荐 def add_item(item, lst=[]): lst.append(item) return lst print(add_item(1)) # [1] print(add_item(2)) # [1, 2] ← 同一个列表被重复使用

代码解析

  • 因为默认参数lst在函数定义时被创建(一个空列表),之后每次调用若不提供lst,都会使用同一个列表对象,导致累积。

  • 解决办法是使用None作为默认值,然后在函数内部创建新列表。

正确做法

def add_item(item, lst=None): if lst is None: lst = [] lst.append(item) return lst

代码解析

  • lst=None:默认值设为不可变对象None

  • if lst is None: lst = []:每次调用时若未传入列表,则新建一个空列表,保证了独立性。

4.3 关键字参数

调用时通过形参名指定实参,可以改变顺序。

def describe_pet(name, species): print(f"{name} is a {species}") describe_pet(species="cat", name="Tom") # Tom is a cat

代码解析

  • describe_pet(species="cat", name="Tom"):显式指定每个参数的名字,顺序可以与定义不同。这样调用时不会受位置影响,增强了可读性。

4.4 可变长度参数

  • *args:接收任意多个位置参数,打包成元组。

  • **kwargs:接收任意多个关键字参数,打包成字典。

def sum_all(*args): return sum(args) print(sum_all(1, 2, 3, 4)) # 10

代码解析

  • *args:收集所有传入的位置参数为一个元组,这里args(1,2,3,4)

  • sum(args):内置函数sum对元组求和,返回10

def print_info(**kwargs): for key, value in kwargs.items(): print(f"{key}: {value}") print_info(name="Alice", age=30, city="Paris")

代码解析

  • **kwargs:收集所有传入的关键字参数为一个字典,这里kwargs{'name':'Alice','age':30,'city':'Paris'}

  • 遍历字典并打印。

4.5 参数组合顺序

在函数定义中,参数的顺序必须是:

  1. 位置参数

  2. 默认参数

  3. *args

  4. 关键字参数(仅限*之后)

  5. **kwargs

def complex_func(a, b=1, *args, c=2, **kwargs): pass

代码解析

  • a是普通位置参数。

  • b=1是默认参数。

  • *args接收多余的位置参数。

  • c=2是仅限关键字参数(必须通过关键字传递)。

  • **kwargs接收多余的关键字参数。


5. 返回值详解

5.1 单个返回值

def square(x): return x ** 2

代码解析:函数返回x的平方,返回后调用方可以接收。

5.2 多个返回值(本质是返回元组)

def get_stats(numbers): return min(numbers), max(numbers), sum(numbers)/len(numbers) low, high, avg = get_stats([1,2,3,4,5]) print(low, high, avg) # 1 5 3.0

代码解析

  • return min(...), max(...), avg(...):实际上返回了一个元组(min, max, avg)

  • 调用方通过low, high, avg = ...进行拆包,分别接收三个值。

5.3return语句省略时返回None

def do_nothing(): pass print(do_nothing()) # None

代码解析:函数没有显式return,默认返回None

5.4return提前退出函数

def is_positive(n): if n > 0: return True return False

代码解析

  • 如果n > 0,执行return True,函数立即结束,不会执行后面的return False

  • 否则执行return False。这种写法可避免使用else


6. 作用域

6.1 局部变量与全局变量

  • 在函数内部赋值的变量是局部变量,只在函数内有效。

  • 在函数外部定义的变量是全局变量,可在函数内读取,但若要修改需用global关键字。

x = 10 # 全局变量 def func(): global x # 声明要修改全局变量 x = 20 y = 5 # 局部变量 func() print(x) # 20

代码解析

  • x = 10:全局变量。

  • def func():内部global x:告诉 Python 这里的x是全局变量,而不是创建局部变量。

  • x = 20:修改全局x的值为 20。

  • y = 5:未声明global,因此是局部变量,函数外部无法访问。

  • 调用func()后,全局x变为 20。

注意:避免过多使用global,推荐通过参数传递和返回值来通信。

6.2nonlocal关键字(用于嵌套函数)

在内层函数中修改外层函数(非全局)的变量。

def outer(): count = 0 def inner(): nonlocal count count += 1 return count return inner counter = outer() print(counter()) # 1 print(counter()) # 2

代码解析

  • outer函数中定义了局部变量count和内层函数inner

  • inner中使用nonlocal count声明要修改的是外层函数outercount变量,而不是创建一个新的局部变量。

  • count += 1修改外层变量。

  • outer返回inner函数对象,形成一个闭包。每次调用counter()都会增加并返回count的值。


7. 函数也是对象

在 Python 中,函数是一等公民,可以赋值给变量、作为参数传递、作为返回值。

def add(a, b): return a + b my_func = add # 赋值 print(my_func(3, 4)) # 7

代码解析:将函数add赋值给变量my_funcmy_func现在指向同一个函数对象,可以像add一样调用。

def apply(func, x, y): return func(x, y) print(apply(add, 5, 6)) # 11

代码解析apply函数接收一个函数作为参数func,然后在内部调用它。这体现了高阶函数的特性。


8. 匿名函数(lambda)

lambda表达式用于创建简单的、单表达式的匿名函数。

square = lambda x: x ** 2 print(square(5)) # 25

代码解析

  • lambda x: x ** 2定义了一个匿名函数,等价于def square(x): return x**2

  • lambda只能包含一个表达式,不能包含语句。

# 常用于 sort 的 key 参数 pairs = [(1, 'one'), (2, 'two'), (3, 'three')] pairs.sort(key=lambda pair: pair[1]) # 按字符串排序

代码解析sortkey参数接收一个函数,用于从每个元素中提取比较键。这里用lambda取每个元组的第二个元素(字符串)作为排序依据。

限制:lambda 只能有一个表达式,不能包含语句(如printreturn等)。


9. 递归函数

函数调用自身称为递归。需要明确的终止条件。

def factorial(n): if n <= 1: return 1 return n * factorial(n - 1) print(factorial(5)) # 120

代码解析

  • if n <= 1: return 1:递归的终止条件,防止无限递归。

  • return n * factorial(n-1):递归调用,每次减少n的值。

  • 调用过程:factorial(5)5 * factorial(4)5 * 4 * factorial(3)→ ... →5 * 4 * 3 * 2 * 1

注意:Python 递归深度有限制(默认约 1000),深层递归建议改用循环。

10. 类型注解(Type Hints)

Python 3.5+ 支持类型注解,提高代码可读性(不强制检查)。

def greet(name: str) -> str: return f"Hello, {name}"

代码解析

  • name: str:表示参数name应为字符串类型。

  • -> str:表示返回值应为字符串类型。

  • 这些注解只是提示,不会在运行时检查类型错误。可以用mypy工具进行静态类型检查。


11. 常见内置函数示例

  • print():输出

  • len():返回长度

  • type():返回类型

  • input():读取用户输入

  • range():生成整数序列

  • sum()max()min()

这些内置函数无需定义,直接使用。

12.常见陷阱与最佳实践

陷阱说明解决方案
使用可变对象作为默认参数函数多次调用共享同一对象使用None并在函数内创建新对象
在函数内修改全局变量未声明会创建同名局部变量使用global或通过参数/返回值传递
混淆位置参数和关键字参数调用时顺序错误明确指定关键字参数名
递归深度过大导致栈溢出递归超过系统限制改用循环或增加sys.setrecursionlimit
忘记return导致返回None预期有返回值但实际为None检查函数所有分支是否都有return
lambda内使用复杂逻辑无法使用语句,代码难读改用普通函数

感谢你的观看,期待我们下次再见!

http://www.jsqmd.com/news/913194/

相关文章:

  • 探秘2026年当下漳州可靠的水果店运营源头公司:全链路赋能新零售 - 2026年企业资讯
  • 光OFDM系统中非线性效应及缓解方法解析【附数据】
  • AI 学习——多 Agent 协作入门
  • 网页切图工具,网格切图,非常方便
  • 基于Arduino与Visuino的线性执行器时序控制系统设计与实现
  • 2026年q2第三方控价选型推荐:线上控价/专业控价/京东控价/化妆品控价/品牌控价/技术与服务双维度解析 - 优质品牌商家
  • 无标识视觉感知下核电厂区外来人员轨迹建模与推演技术解析
  • 别再只懂LSH了:手把手拆解跨模态哈希中的矩阵分解与离散优化(附Python示例)
  • Hotkey Detective:3分钟精准定位Windows热键冲突的终极方案
  • D41: 多租户架构的 AI 服务设计
  • 2026年5月,专业儿童帽企业的硬核实力与深度服务解析 - 2026年企业资讯
  • 两个独立事件的联合概率
  • 下载 | Win10 2021官方精简版,预装应用极少!(5月更新、Win10 IoT LTSC 2021版、适合老电脑)
  • 收藏!AI时代,被淘汰的不是程序员,而是那些不懂“借力”的人!
  • 从零开发游戏需要学习的c#模块,第三十章(掉落物品 —— 血包与能量)
  • 【PC】《剪映助手悬浮球V2.1》支持最新剪映
  • 2026年北京老家具回收机构排行 靠谱之选盘点 - 优质品牌商家
  • 智能锁怎么选,家用推荐哪个品牌型号?
  • 千问大模型在阿里生态中的实战应用指南
  • 收藏!Python小白必看:从零入门大模型,手把手带你掌握企业级实战能力
  • 2026年网红香薰厂家核心服务及对接联系方式解析 - 优质品牌商家
  • SQL分组查询不会用?手把手教你Group By和聚合函数
  • 告别调包:用NumPy在头歌EduCoder里手动实现CNN的前向传播(含维度计算详解)
  • Windows 10下用IDEA跑通ThingsBoard 3.4源码:保姆级环境配置与编译避坑指南
  • 从PCA到PLS-DA:当你的组学数据‘分不开’时,试试这个有监督的降维利器(附R代码避坑指南)
  • 从零开始:用Python和Scikit-learn搭建你的第一个AI面试助手(附常见问题库)
  • 合作获客平台怎么选?10大渠道深度解析,智能匹配工具成新趋势!
  • 专访 7 名普通职场人:AI 来了之后,你过得还好吗?
  • 面向核电涉密场景的非接触式人员全域定位算法优化方案
  • 2026年q2:美业新商机/美业项目/自主创业项目/连锁品牌加盟/EF时尚假发核心业务与技术体系全解析 - 优质品牌商家