Python 中将函数存储在模块中:五种导入方式
本文档面向零基础新手,详细讲解什么是模块、如何把函数写在模块里,以及 Python 中五种常用的导入方式的写法、区别和注意点,并配有大量示例。
第一部分:什么是模块?为什么要把函数放在模块里?
一、模块的概念
模块(module) 就是一个以 .py 结尾的 Python 文件。这个文件里可以写变量、函数、类等。别的 Python 程序可以通过 import 把这个文件“引入”进来,使用里面定义好的函数或变量。
可以简单记:
- 模块 = 一个
.py文件 - 把函数写在模块里 = 把函数写在这个
.py文件里,以后在别的文件里“导入”再调用
好处:
- 代码分开:主程序只写“做什么”,具体实现放在模块里,主程序更短、更清晰
- 复用:多个程序可以共用同一份模块,不用复制粘贴
- 维护:改函数逻辑时只改模块文件,所有导入它的程序都会用到新逻辑
二、先准备一个“模块文件”示例
后面所有“导入方式”的示例,都会用到下面这个模块。请你先在同一目录下新建一个文件,例如:my_utils.py(名字可以自取,但不要用数字开头,不要有空格),内容如下:
# my_utils.py —— 这是一个“模块”,里面放了几个函数
def greet(name):
"""和 name 打招呼"""
return "你好," + name
def add(a, b):
"""求 a + b"""
return a + b
def multiply(a, b):
"""求 a * b"""
return a * b
PI = 3.14159 # 模块里也可以放变量,供别人导入使用
这个文件就是我们的自定义模块,里面有 3 个函数和 1 个变量。下面在另一个文件(例如 main.py,和 my_utils.py 放在同一文件夹里)里演示五种导入方式。
重要: 默认情况下,Python 只会从当前运行脚本所在目录以及标准库路径里找模块。所以练习时请把“调用方”脚本(如 main.py)和模块文件(如 my_utils.py)放在同一目录下。
第二部分:五种导入方式详解
三、方式一:import 模块名(导入整个模块)
写法:
import 模块名
含义: 把整个模块“搬进来”,使用其中的函数或变量时,必须写成 模块名.函数名 或 模块名.变量名。
示例(在 main.py 中):
import my_utils
print(my_utils.greet("小明")) # 你好,小明
print(my_utils.add(3, 5)) # 8
print(my_utils.multiply(2, 4)) # 8
print(my_utils.PI) # 3.14159
特点:
- 优点:一眼就能看出某个函数或变量来自哪个模块,不会和当前文件里的名字冲突
- 缺点:每次调用都要写“模块名.”,稍长一点
注意: 这里的“模块名”是文件名去掉 .py。例如文件叫 my_utils.py,就写 import my_utils,不能写 import my_utils.py。
四、方式二:from 模块名 import 函数名(导入指定的函数或变量)
写法:
from 模块名 import 函数名或变量名
可以写多行,也可以在一行里用逗号分隔导入多个名字:
from 模块名 import 函数名1, 函数名2, 变量名
含义: 只把该模块里指定的函数(或变量)“拿进来”,使用时直接写函数名,不需要再加“模块名.”。
示例(在 main.py 中):
from my_utils import greet, add
print(greet("小红")) # 你好,小红(直接用 greet,不用写 my_utils.greet)
print(add(10, 20)) # 30
# print(multiply(2, 3)) # 若没导入 multiply,这里会报错:NameError
再导入变量:
from my_utils import greet, add, PI
print(PI) # 3.14159
特点:
- 优点:调用时简短,直接写函数名
- 缺点:如果当前文件里也定义了同名的函数或变量,会覆盖导入的名字,容易搞混;读代码时有时看不出这个名字来自哪个模块
五、方式三:from 模块名 import 函数名 as 别名(导入并起别名)
写法:
from 模块名 import 函数名 as 别名
含义: 导入该函数(或变量),但在当前文件里用另一个名字来用,避免名字太长或和本文件里的名字冲突。
示例(在 main.py 中):
from my_utils import greet as say_hi
from my_utils import multiply as mul
print(say_hi("小刚")) # 你好,小刚(用别名 say_hi 调用)
print(mul(3, 4)) # 12(用别名 mul 调用,比 multiply 短)
常见用途:
- 模块名或函数名太长,用短一点的别名
- 当前文件里已有同名函数,用别名区分“是模块里的那个”
六、方式四:import 模块名 as 别名(导入整个模块并起别名)
写法:
import 模块名 as 别名
含义: 导入整个模块,但在当前文件里用别名来引用它。调用时写 别名.函数名、别名.变量名。
示例(在 main.py 中):
import my_utils as utils
print(utils.greet("小明")) # 你好,小明
print(utils.add(1, 2)) # 3
print(utils.PI) # 3.14159
常见用途:
- 模块名很长时,用短别名,例如:
import numpy as np、import matplotlib.pyplot as plt
七、方式五:from 模块名 import *(导入模块中的“所有”公共名字)
写法:
from 模块名 import *
含义: 把该模块里所有对外公开的名字(一般是不以下划线开头的)都导入到当前文件,使用时直接写函数名或变量名,不需要“模块名.”。
示例(在 main.py 中):
from my_utils import *
print(greet("小明")) # 你好,小明
print(add(2, 3)) # 5
print(multiply(2, 3)) # 6
print(PI) # 3.14159
为什么一般不推荐:
- 可读性差:看代码时很难一眼看出
greet、add来自哪个模块,项目一大就容易乱 - 容易覆盖:模块里名字很多时,很容易和当前文件里的变量或函数同名,导致被覆盖或难以排查 bug
- 规范建议:PEP 8 等风格指南建议尽量避免
import *
什么时候勉强可以用: 只在很小的、自己写的练习脚本里图方便时用一下;正式项目或和别人协作时,更推荐用方式一或方式二。
第三部分:五种方式对比小结
八、对照表
| 导入方式 | 写法示例 | 调用方式 | 适用场景 |
|---|---|---|---|
| 方式一 | import my_utils |
my_utils.greet("小明") |
需要明确标出来源,避免重名 |
| 方式二 | from my_utils import greet, add |
greet("小明")、add(1,2) |
只用少数几个函数,想写短一点 |
| 方式三 | from my_utils import greet as say_hi |
say_hi("小明") |
想用短名或避免和本文件同名冲突 |
| 方式四 | import my_utils as utils |
utils.greet("小明") |
模块名太长,用短别名 |
| 方式五 | from my_utils import * |
greet("小明") |
不推荐,仅小练习可偶尔用 |
九、同一次运行中,模块只会被加载一次
无论你用哪一种方式写了几行 import,只要模块名相同,Python 在同一次运行里只会执行该模块文件一次。之后的 import 只是复用已经加载好的那个模块,不会重复执行模块里的顶层代码。例如:
# main.py
import my_utils # 第一次:执行 my_utils.py
import my_utils # 第二次:不再执行,直接用已加载的
通常我们每个模块只写一行导入即可。
第四部分:常见问题与注意点
十、模块文件放在哪里?
- 同一目录(推荐新手):把
my_utils.py和main.py放在同一个文件夹里,在终端里进入该文件夹,执行python main.py,即可正常import my_utils。 - 其他目录:要把“模块所在目录”加入 sys.path,或把模块放在已在该路径下的包(package)里,才能被导入。新手先把模块和主程序放同一目录即可。
十一、模块名(文件名)的命名建议
- 使用小写字母、数字、下划线,例如:
my_utils.py、game_helpers.py - 不要用数字开头(如
1_utils.py),不要用空格和连字符(如my-utils.py),否则导入时不方便
十二、若模块里有“测试代码”,不想在导入时执行
有时模块里会写一些“只有直接运行这个文件时才执行”的测试代码,而不希望被别人 import 时执行,可以这样写:
# my_utils.py
def greet(name):
return "你好," + name
if __name__ == "__main__":
# 只有直接运行 python my_utils.py 时才会执行下面这段
print(greet("测试"))
解释: 当直接运行 my_utils.py 时,Python 会把该文件的 __name__ 设为 "__main__",于是 if __name__ == "__main__": 成立,测试代码会执行。当别人在别的文件里写 import my_utils 时,my_utils 的 __name__ 是 "my_utils",不是 "__main__",这段测试代码就不会执行。
十三、导入标准库或第三方库时用法一样
这五种方式不仅适用于你自己写的 .py 模块,也适用于 Python 标准库和第三方库:
import os
print(os.getcwd())
from math import sqrt
print(sqrt(4)) # 2.0
import math as m
print(m.pi)
from random import randint
n = randint(1, 10)
语法规则相同:模块名对应该库的包/模块名(通常和 import 时写的名字一致)。
第五部分:小结
- 模块 = 一个
.py文件,里面可以放函数、变量等,供其他文件导入使用。 - 五种导入方式:
import 模块名→ 用模块名.函数名from 模块名 import 函数名→ 直接用函数名from 模块名 import 函数名 as 别名→ 用别名import 模块名 as 别名→ 用别名.函数名from 模块名 import *→ 直接用所有公开名字(不推荐)