Python函数定义与调用基础教程

Nora
Nora
发布时间:2026-10-30| 8人浏览过
原创

系统讲解Python中函数的定义语法、调用执行流程、形参与实参传递方式、返回值机制以及局部作用域规则,结合完整代码示例与结构图示,帮助初学者扎实掌握函数核心用法。

函数是 Python 中组织可复用代码的基本单元。当一段特定逻辑需要在多处使用,或者程序变得复杂需要按功能拆解时,编写函数可以避免代码重复并提高整体可维护性。本文将完整讲解函数的定义语法、调用机制、参数传递方式以及返回值处理,帮助读者掌握从声明到调用的标准操作流程。

一、定义与调用的基本语法

在 Python 中,定义函数使用 def(define 的缩写)关键字,基本格式包含函数名称、圆括号内的参数列表、末尾的英文冒号以及保持统一缩进的代码块。

def calculate_area(width, height):
    """计算并返回矩形面积"""
    area = width * height
    return area

# 调用函数并接收结果
result = calculate_area(5, 3)
print(result)
示例运行输出
15

上述代码展示了一个标准的函数结构:第一行声明函数名与接收数据的形参;第二行是可选的三引号文档字符串(docstring),用于对函数功能进行解释;第三行执行计算;第四行通过 return 将计算得到的数据返回给调用方。在脚本下方,通过书写 calculate_area(5, 3) 即可完成调用并传入实际数值。

Python函数定义与调用基础教程
图 1:Python 函数定义的核心语法组成与说明

二、函数的生命周期与执行步骤

理解函数运作的关键在于分清“定义期”与“调用期”的差异。很多初学者容易误以为定义函数时代码就已经在运行,实际并非如此。

在 Python 脚本自上而下解析时,遇到 def 语句仅仅是在当前作用域中创建了一个函数对象,并将函数名绑定到该对象上,函数体内部的代码并不会立即运行。只有当解释器扫描到函数名称后面带有英文括号 () 的调用表达式时,才会正式暂停当前外部代码流,跳转进入函数体内部逐行执行,完成后再带着结果返回原调用点。

Python函数定义与调用基础教程
图 2:函数从定义到调用的五阶段控制流推进图

避坑提醒:函数名与函数调用的本质区别

在代码中写 func 和写 func() 含义完全不同:func 指的是该函数对象本身,打印它只会得到对象内存地址;只有加上圆括号 func(),才代表命令 Python 执行该函数并获取返回值。

三、参数传递方式:位置参数 vs 关键字参数

在调用函数时,如何把外部的数据精准传递给函数内部的形参,是编写清晰代码的关键。在统一的函数声明下,Python 主要支持两种传参方式:位置参数与关键字参数。

def send_message(recipient, text, urgent=False):
    """模拟发送通知消息"""
    tag = "[加急]" if urgent else "[常规]"
    print(f"{tag} 向 {recipient} 发送内容:{text}")

# 方式 1:按位置传递
send_message("张三", "会议安排在下午两点", True)

# 方式 2:按关键字指定传递
send_message(text="明天请提交报告", recipient="李四")
示例运行输出
[加急] 向 张三 发送内容:会议安排在下午两点
[常规] 向 李四 发送内容:明天请提交报告

关键差异对比与影响分析

理解这两种传参方式的根本差异对于编写健壮代码至关重要:

  • 依赖维度不同:位置参数完全依赖实参在括号里的先后次序;关键字参数则依据参数名称进行匹配,与调用书写的顺序完全无关。
  • 对代码可读性的影响:当函数参数较多或存在布尔标志位时,使用位置参数调用(例如 send_message("张三", "通知", True))往往让阅读者难以快速理解 True 代表什么含义;而改用关键字参数 urgent=True 则具备自解释性。
  • 混合调用规则:在同一调用中混合使用两者时,位置参数必须严格置于关键字参数的左侧。若写成 send_message(recipient="张三", "通知"),Python 会在语法解析阶段直接抛出 SyntaxError: positional argument follows keyword argument。
Python函数定义与调用基础教程
图 3:位置参数与关键字参数在传参映射与语义表达上的详细对比

四、返回值与局部作用域边界

函数通过 return 语句将数据输出给调用方。如果在函数体中没有书写 return,或者只写了单独的 return 关键字而没有跟任何表达式,Python 会默认返回 None。

def divide_numbers(a, b):
    if b == 0:
        print("除数不能为0")
        return  # 提前终止函数,此时返回 None
    quotient = a // b
    remainder = a % b
    return quotient, remainder  # 返回多个值,自动打包为元组

# 场景 1:正常除法,获取商与余数
q, r = divide_numbers(10, 3)
print(f"商: {q}, 余数: {r}")

# 场景 2:异常除0,检验默认返回值
err_val = divide_numbers(10, 0)
print(f"返回值结果: {err_val}")
示例运行输出
商: 3, 余数: 1
除数不能为0
返回值结果: None

除返回值外,另一个不可忽视的基础概念是局部作用域(Local Scope)。在函数内部创建的变量(例如 quotient 与 remainder)仅存在于该函数的运行周期中。当函数运行完毕退出时,其局部命名空间将被立即回收。若尝试在函数体外部直接访问这些内部变量,Python 将抛出 NameError: name 'quotient' is not defined。这种隔离机制保证了各个函数之间互不干扰,避免命名污染。

五、核心机制与避坑规则总结

在熟练使用函数前,需要对几个最容易出错的底层细节形成清晰的判断依据:

Python函数定义与调用基础教程
图 4:Python 函数核心使用规则与关键排错要点总览

经典陷阱:慎用可变对象作为默认参数

如果在定义时写 def append_item(val, container=[]),列表 [] 只会在定义期被创建一次。后续所有未显式传入 container 的调用都会共享同一个列表对象,导致多次调用的数据累积污染。标准写法应将默认值设为不可变的 None,并在函数内部通过 if container is None: container = [] 动态创建。

掌握函数的标准定义格式、调用语法、实参与形参的传递逻辑以及作用域规则后,就可以根据业务需求将重复的代码块抽离为模块化函数,为编写结构严密、可维护的 Python 应用程序打下坚实基础。

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。