Python函数与模块怎么定义和调用?新手入门指南
本指南面向零基础及初学者,全面讲解Python函数的定义、参数传递与返回值处理,以及自定义模块的编写、多文件导入与跨文件调用方法,并结合图解与实战示例解析常见避坑要点。
初学 Python 编写程序时,多数人会把所有逻辑顺次写在同一个脚本里。随着功能增加,代码行数迅速突破数百行,重复逻辑不断出现,查找和修改一个细节变得异常繁重。解决这个问题的核心武器正是函数(Function)与模块(Module):函数负责把完成特定任务的代码段打包成可复用单元;模块则把相关的函数组织在独立文件中供全局调用。本文将直接从具体语法、内存流转到跨文件组织,帮助你彻底掌握两者的定义与调用方式。
一、Python 函数的定义与基本调用
函数本质上是一段封装好的、带有名称的代码块。只有在被主动调用时,它才会执行。定义函数能够消除大量复制粘贴的代码,并且让主业务流程清晰明了。
1. 函数的定义语法
Python 使用关键字 def(define 的缩写)声明函数,其标准结构包含函数名称、接收参数的圆括号、冒号以及缩进的代码体:
# 定义计算两数之和的函数
def calculate_sum(a, b):
"""计算两数相加并返回结果(文档字符串)"""
result = a + b
return result
上述代码包含几个关键组成部分:
def:告诉 Python 解释器即将定义一个函数。calculate_sum:函数名称,遵循小写字母加下划线的命名规范。(a, b):形式参数(形参),充当函数内部接收外部数据的占位符。:与缩进:冒号后紧跟缩进块,缩进范围内的语句构成函数体。"""文档字符串""":用三引号包裹的说明文字,便于后续查阅该函数的作用。return:将内部计算结果传递回函数外部;若省略return,函数默认返回None。
2. 函数的调用过程
定义函数仅是在内存中创建了一个可执行对象,并不会立即运行其中的逻辑。执行函数必须通过“函数名 + 圆括号”完成,并在括号内传入具体数值(实参):
# 调用函数并保存返回值
total = calculate_sum(15, 25)
# 输出结果
print("计算结果是:", total)
# 输出示例: 计算结果是: 40
当解释器执行到 calculate_sum(15, 25) 时,会将数字 15 赋值给形参 a,将 25 赋值给形参 b,跳转执行函数体,最终把 40 替换回调用处并赋值给变量 total。
二、深入掌握函数参数与返回值传递
为了让函数适应不同场景,Python 提供了丰富灵活的参数传递机制。
1. 位置参数与关键字参数
最基本的参数传递是位置参数,实参依照书写顺序与形参一一对应;而关键字参数则允许在调用时显式指定形参名称,不再受顺序限制:
def print_student_info(name, age, city):
print(f"姓名: {name}, 年龄: {age}, 城市: {city}")
# 位置参数:按顺序传入
print_student_info("张三", 20, "北京")
# 关键字参数:明确指明参数名,顺序可颠倒
print_student_info(city="上海", name="李四", age=22)
2. 默认参数(缺省参数)
在定义函数时,可以直接为形参赋予默认值。如果调用时没有传对应实参,函数就会采用默认值:
def greet(user_name, greeting="你好"):
return f"{greeting},{user_name}!"
# 使用默认问候语
print(greet("小明")) # 输出: 你好,小明!
# 覆盖默认问候语
print(greet("Alice", "Hello")) # 输出: Hello,Alice!
def fn(a, b=1): 合法,而 def fn(a=1, b): 会直接引发语法错误 SyntaxError)。此外,绝不要使用列表(list)或字典(dict)等可变类型作为默认参数值。
3. 多返回值与解包
很多语言只允许函数返回单个变量,但在 Python 中,使用逗号分隔多个值即可一次性返回多种数据。其底层是将数据打包成元组(tuple),调用者可以通过多变量直接解包:
def get_min_max(numbers):
min_val = min(numbers)
max_val = max(numbers)
return min_val, max_val # 实际上返回的是一个元组 (min_val, max_val)
# 调用并进行变量解包
smallest, largest = get_min_max([12, 45, 3, 89, 21])
print(f"最小值: {smallest}, 最大值: {largest}")
# 输出示例: 最小值: 3, 最大值: 89
三、从单个脚本到模块化:模块的定义
当项目包含数十个甚至上百个函数时,若全部堆放在一个 main.py 中,查找逻辑将变得极其痛苦。这时就需要对代码进行“模块化”拆分。
1. 什么是 Python 模块?
在 Python 中,任何一个以 .py 为扩展名的代码文件都可以作为一个模块。模块文件名(去掉 .py 后缀)就是该模块的名称。模块中可以包含函数、类、全局变量以及可执行代码。
2. 创建自定义模块实操
创建模块非常简单:在你的项目工作目录下新建一个 .py 文件即可。比如我们创建一个名为 math_tools.py 的文件,并写入以下函数和变量:
# 文件名: math_tools.py
# 这是一个自定义的数学工具模块
PI = 3.1415926535
def add(x, y):
"""返回两数相加"""
return x + y
def subtract(x, y):
"""返回两数相减"""
return x - y
def circle_area(radius):
"""根据半径计算圆面积"""
return PI * (radius ** 2)
此时,math_tools.py 已经成为一个完全合法的 Python 模块。接下来就可以在其他脚本文件中引用它。
四、模块的导入(Import)与调用方法
在另一个文件(例如同一目录下的 main.py)中使用模块中的函数,必须先使用 import 语法将其引入当前命名空间。常见的导入方式有以下三种:
方式 1:完整导入模块(import module_name)
这是最稳妥的导入方式。导入整个模块后,使用 模块名.函数名() 的点号语法调用目标函数:
# 文件名: main.py
import math_tools
# 通过 模块名. 访问内部函数与常量
result_add = math_tools.add(10, 5)
area = math_tools.circle_area(3)
print("加法计算:", result_add) # 输出: 15
print("圆面积:", area) # 输出: 28.2743338815
优点:能够保留完整的命名空间前缀,哪怕当前文件也定义了同名的 add 函数,两者也不会产生冲突。
方式 2:精准导入指定函数(from module_name import function_name)
如果只需要模块中的某几个特定函数,可以直接精准导入:
# 文件名: main.py
from math_tools import add, circle_area
# 直接调用函数名称,无需加模块名前缀
result = add(20, 30)
print("直接调用加法:", result) # 输出: 50
注意:如果当前脚本中恰好有同名函数,后定义的函数会覆盖先前导入的函数,因此要注意命名冲突问题。
方式 3:导入并设置别名(import ... as alias)
当模块名称较长或为了书写简练时,可以使用 as 关键字设置缩写别名(在数据科学库如 import numpy as np 中广泛使用):
# 文件名: main.py
import math_tools as mt
# 使用简写别名进行调用
res = mt.subtract(50, 18)
print("减法计算:", res) # 输出: 32
from math_tools import *。这种星号通配符导入会将模块内的所有变量和函数一股脑灌入当前文件,不仅降低代码可读性(让人无法辨别某个函数到底来自哪个模块),还极易无声无息地覆盖掉当前文件的同名变量。
五、模块的实战进阶技巧与避坑指南
1. 关键守护:if __name__ == '__main__': 的作用
当我们在编写 math_tools.py 模块时,往往想在文件底部写几句测试代码看它能不能正常工作。但如果直接写 print(add(2, 3)),当别人 import math_tools 时,这句测试打印也会跟着执行。
为了解决这个问题,Python 提供了解释器内置变量 __name__:
- 直接以主程序运行该文件(如在终端执行
python math_tools.py)时,__name__会被自动设为"__main__"。 - 作为模块被其他文件
import时,__name__的值是模块文件名(即"math_tools")。
# 文件名: math_tools.py
def add(a, b):
return a + b
# 仅在直接运行该脚本时执行内部测试;被其他文件导入时此代码块被完全忽略
if __name__ == "__main__":
print("模块本地测试运行开始:")
print("2 + 3 期望为 5,实际结果是:", add(2, 3))
2. 为什么提示找不到模块(ModuleNotFoundError)?
当尝试导入模块却报错 ModuleNotFoundError: No module named 'xxx' 时,通常是解释器的搜索路径问题。Python 导入模块时,会在内置变量 sys.path 包含的路径列表中按顺序查找:
- 当前执行脚本所在的目录(优先级最高);
- 环境变量
PYTHONPATH指定的路径; - Python 官方标准库和第三方虚拟环境的
site-packages目录。
如果你自定义的模块与主运行脚本位于同一文件夹下,可以直接导入;如果模块在子文件夹或上级文件夹,需要通过包(Package)相对路径导入或通过设置目录环境变量来解决。
六、新手实战速查总结
为了在实际写代码时快速回忆与对照,我们将函数与模块的核心操作整理如下:
| 操作类型 | 基础语法示例 | 关键作用与适用场景 |
|---|---|---|
| 函数定义 | def my_func(x, y=10): ... |
封装特定功能的逻辑块,支持默认参数与多返回值。 |
| 函数调用 | res = my_func(5, y=20) |
通过位置或关键字传递数据,执行内部逻辑并获得返回值。 |
| 模块创建 | 新建普通 .py 文件(如 tools.py) |
按业务领域将通用函数、变量收拢至同一物理文件。 |
| 模块完整导入 | import tools |
完整载入模块命名空间,通过 tools.fn() 安全调用。 |
| 特定符号导入 | from tools import add |
直接引入目标函数至当前作用域,无需加模块前缀。 |
| 入口守卫 | if __name__ == '__main__': |
隔离文件自身测试代码与外部导入执行流程。 |
函数实现了“代码逻辑维度的重用”,模块实现了“文件与工程维度的组织”。在日常开发中,先从将 10 行以上的重复代码抽象为函数开始,再逐渐将功能相近的函数归拢到独立 .py 模块中,你的 Python 代码结构就会变得越来越干净、健壮且易于扩展。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













