python中的import和from两种导入方式有什么区别
这是一个非常核心的Python问题。简单来说,import
导入的是整个“工具箱”,而 from ... import
是从工具箱里拿出特定的“工具”。
下面我们来详细分解它们的区别。
核心概念比喻
import module_name
你把整个工具箱 (
module_name
) 搬进来。每次想用里面的扳手 (function_name
) 时,你都需要指明是哪个工具箱的,比如module_name.function_name()
。from module_name import function_name
你只从工具箱里拿出你需要的那个扳手 (
function_name
)。现在你可以直接使用这个扳手,比如function_name()
,而不用再提工具箱的名字。**
from module_name import ***
你把整个工具箱里的所有工具都倒了出来,铺了一地。你可以直接使用任何工具,但很可能搞不清楚哪个工具是哪个工具箱的了,容易造成混乱(不推荐)。
详细区别对比
特性 | import module_name | from module_name import something |
---|---|---|
访问方式 | 必须使用完整名称(模块名.函数名)module_name.function_name() | 可以直接使用导入的对象名function_name() |
命名空间 | 将整个模块引入到当前命名空间,但访问其内容仍需通过模块名。保持了清晰的命名空间隔离。 | 将模块中的特定对象引入到当前命名空间。可能会污染当前命名空间,导致名称冲突。 |
可读性 | 代码中清晰可见函数或类的来源,易于理解和维护。 | 代码更简洁,但有时难以快速判断一个函数是从哪个模块导入的。 |
内存占用 | 理论上会加载整个模块,占用稍多内存。但模块通常只加载一次,实际差异很小。 | 只加载并导入指定的对象,但本质上整个模块还是被加载到内存中,差异可忽略不计。 |
重命名 | 通常与 as 联用给模块起别名:import numpy as np | 可以在导入时给对象起别名,解决命名冲突:from pandas import DataFrame as DF |
代码示例
假设有一个模块 math_utils.py
,里面有两个函数:
python
# math_utils.py def add(a, b):return a + bdef multiply(a, b):return a * b
1. 使用 import
python
import math_utilsresult = math_utils.add(5, 3) print(result) # 输出:8# 这样写很清晰,我们一眼就能看出 add 来自 math_utils 模块。
2. 使用 from ... import ...
python
from math_utils import addresult = add(5, 3) # 直接使用函数名,无需模块前缀 print(result) # 输出:8# 注意:此时只能使用 add 函数 # multiply(5, 3) # 这行会报错,因为 multiply 没有被导入到当前命名空间
3. 处理名称冲突(起别名)
python
# 假设我们自己的代码里已经有一个叫 `add` 的函数 def add(a, b):return f"Custom add: {a + b}"# 方法一:使用 import module,绝对不会冲突 import math_utils print(add(1, 2)) # 输出:Custom add: 3 print(math_utils.add(1, 2)) # 输出:3# 方法二:使用 from ... import ... as ... 起别名 from math_utils import add as math_add print(add(1, 2)) # 输出:Custom add: 3 print(math_add(1, 2)) # 输出:3
优缺点总结与建议
import module_name
优点:命名清晰,不易冲突。是大多数情况下推荐的做法,尤其是在编写大型项目或库时。
缺点:代码稍长。
from module_name import something
优点:代码简洁,对于常用函数(如
os.path.join
)写起来更方便。缺点:容易引起命名空间污染。如果你导入了两个模块的同名函数,后导入的会覆盖先导入的,导致难以调试的bug。
最佳实践
优先使用
import module_name
:尤其是在导入多个模块时,这是最安全、最清晰的方式。给常用模块起短别名(如import numpy as np
,import pandas as pd
)是标准做法。谨慎使用
from ... import ...
:适用于频繁使用某个模块下的特定函数或类,并且能确保不会与当前命名空间的名称冲突。
常用于从自定义的本地模块或父包中导入(如
from .submodule import MyClass
)。
绝对避免
from ... import *
(通配符导入):这会让代码变得极其难以理解和维护,因为你根本不知道当前命名空间里有哪些名字。
PEP8(Python官方风格指南)明确不推荐这种做法。唯一的例外可能是在交互式命令行(Python Shell)中为了快速测试而使用。
结论:没有绝对的优劣,根据场景选择。为了代码的长期可维护性,import module_name
通常是更稳妥和 professional 的选择。from ... import ...
在确保无冲突的前提下,可以用来简化代码。