为什么在Python中推荐使用 import 而不是 from...import 语句?

byte of python chinese version 72 页 如果导入到 mymodule 中的模块里已经存在了__version__这一名称,那将产生冲突。这可能是因为每个模块通常都会使用这一名称来声明它们各自的版本号。因此,我们大都推荐最好去使用 import 语句,尽管这会使你的程序变得稍微长一些。

搜索看了好几个地方,还是不是特别明白。求指教~谢谢~


为什么在Python中推荐使用 import 而不是 from...import 语句?
16 回复

感觉他这句话已经说到位了啊。


在Python中,import modulefrom module import something 各有优劣,但通常更推荐前者,主要有几个原因。

首先,import module 能保持命名空间的清晰。当你直接导入整个模块时,所有内容都通过 module.xxx 的方式访问,一眼就能看出某个函数或类来自哪个模块,避免了命名冲突。比如,如果两个模块都有个 open() 函数,用 import osimport mymodule 后分别用 os.open()mymodule.open() 就很清楚。

其次,它更利于代码的可读性和维护。读代码的人看到 numpy.array() 立刻知道这是NumPy的数组,而不是别的什么。如果用了 from numpy import array,后面直接写 array(),在大型项目或多人协作时,时间一长可能就记不清这个 array 的具体来源了。

另外,import module 能避免循环导入问题变得更复杂,并且让模块的依赖关系更明确。虽然 from...import * 是最不推荐的(因为它会污染命名空间且完全不清楚导入了什么),但即使是具体的 from...import name,在导入很多项时也会让代码开头变得冗长。

当然,from...import 也有它的场景,比如在模块内部频繁使用某个子模块时(from collections import defaultdict),或者为了兼容性而重命名时。但总的来说,默认使用 import module 能让代码更健壮、更易懂。

一句话建议:优先用 import module 来保持代码清晰和避免命名冲突。

他说得很明白了啊,version 这样的名称太过于常见了,它更适合看作是 module.version 的一个属性,而不是单独的变量。所以 import module, 然后 module.version 是合适的。
但是,如果是一个特定的类,例如 from collections import OrderedDict,OrderedDict 可以独立使用的类,那么 from…import 并没有问题。

表示明白了很多~谢谢~

应该是不推荐使用 from … import * 语句吧?

这个倒挺有用的,可以通过 all 来限制 from … import * 导入的东西,很多库都会用到。

《 The Hitchhiker ’ s Guide to Python 》( http://docs.python-guide.org/en/latest/writing/structure/#modules )中解释:import foo这种方式更有助于可读性,在函数调用时(foo.bar())能够让人一眼辨认出使用的函数来自于哪个 Module,提高了可读性和易于理解(单文件的简单代码除外)。而from foo import bar这种方式,仅仅在之后的调用中能够省略一些输入。

from xyz import abcd, efgh 这么一下子进来了两个或多个名字. 如果这些个名字都不是很广为人知的话,是更容易引起名称冲突的.

from 没有不建议使用。只是不建议用*。
Django 系非常喜欢用 from。

在不同的书中推荐的也不一样。总结来看是这样子的

- 推荐 import 的理由是防止命名空间的污染,使用起来有逻辑一眼就看出从哪个包出来的
- 推荐使用 from xxx import xxx 的理由是按需导入,减少内存的占用,容易污染当前命名空间

所以还是 直接 import 好像比较好,内存什么的只要不爆炸都好说。

这个和 c++ std 包不建议 using 是同样的道理

应该是不推荐使用 from … import * , 否者__version__哪里来的冲突,没有人会导入__version__吧。

#5
__all__严格来说应该是限制 module 导出的东西,确实很多库用到了这个特性来隐藏一些写在 module 中的私有类 /函数
但是一个库还是应该导出了__version__的吧,from … import * 名称污染不可避……




import * 不会导入 module 里面下划线开头的东西,所以除非显示声明了 versionall 里面,否则是不会自动导入的,所以也不存在 version 的冲突或名称污染。

all 的作用就是用来重写 import * 的行为,可以用来隐藏 public property, 也可以暴露 private property.

忘了哪本书说的了,import 限定了字典查找的范围,资源消耗少。如果全部搞一起,查起来费力了。

不建议 from … import * 吧,看过这个说法,主要是为了防止命名冲突

回到顶部