python中对模块引入的辨析

import..fromimport的差异

首先我们要说明:

依赖库里面是有很多个,模块的,我在今天学习的tomllib是自带模块的其中之一罢了:

from tomllib import * 的情况

当使用 from tomllib import * 语句时,确实会将 tomllib 模块中所有定义的公共对象(函数、类、变量等)直接导入到当前 .py 文件的命名空间中。导入之后,在当前文件里可以直接使用这些对象,无需再加上模块名作为前缀。不过,这种导入方式存在命名冲突的风险。

例如,假设 tomllib 模块中有一个 load 函数,同时你的当前文件中也定义了一个名为 load 的函数,使用 from tomllib import * 导入后,tomllib 中的 load 函数可能会覆盖你自己定义的 load 函数,或者反之,从而导致意外的结果。示例如下:

1
2
3
4
5
6
7
8
9
# 假设 tomllib 模块中有 load 函数
from tomllib import *

# 假设当前文件中也定义了一个 load 函数
def load():
print("This is my own load function.")

# 这里调用的 load 函数可能会产生混淆
load()

import tomllib 的情况

使用 import tomllib 语句时,Python 会将 tomllib 模块加载到当前程序的命名空间中,并且创建一个指向该模块的引用。虽然不是将模块中的所有函数和对象 “复制” 到当前文件的命名空间,但实际上这些函数和对象已经被加载到内存中,只是在使用时需要通过 tomllib.函数名tomllib.对象名 的方式来引用。

这样做的好处是可以明确指出函数或对象的来源,避免命名冲突。例如:

1
2
3
4
5
import tomllib

# 这里明确调用的是 tomllib 模块中的 load 函数
with open('config.toml', 'rb') as f:
data = tomllib.load(f)

总结

  • from tomllib import *:会将 tomllib 模块中的所有公共对象直接导入到当前命名空间,使用时无需加模块名前缀,但容易引发命名冲突,不建议在实际项目中大量使用。
  • import tomllib:将 tomllib 模块加载到当前程序中,通过 tomllib.对象名 的方式使用模块中的对象,能有效避免命名冲突,提高代码的可读性和可维护性。

另外,还有一种折中的方式 from tomllib import load,这种方式只导入 tomllib 模块中的 load 函数到当前命名空间,既可以直接使用 load 函数,又能避免导入过多不必要的对象,减少命名冲突的可能性。

  • 除了上述的我们探讨的会引起大量冲突的情况,以下情况是对加不加前缀的最简单的解释:

    import后面只要是类或者具体方法名字,由于足够具体,可不用加前缀,只要import后面是库或者模块,都要加前缀,因为范围太大,不管有没有from关键字。

    并且,不可以直接在import后面加上具体方法和类明,import后面只可以加库或者模块名。