从X导入a'与'import X; X.a
我看到一些Python程序员经常使用一种风格(我们称之为风格1):
import some_module
# Use some_module.some_identifier in various places.
支持这种风格的一个理由是,大家都知道“明确比隐含好”这句话。我也见过其他程序员使用另一种风格(风格2):
from some_module import some_identifier
# Use some_identifier in various places.
我觉得风格2的主要好处在于可维护性——特别是当我想用一个模块替换另一个模块时,比如用某个模块替换成另一个模块,这种情况在“鸭子类型”的理念下很常见。我还觉得风格2在“可读性很重要”这句话上更有优势。虽然我个人不太同意,但有人可能会说,使用风格1时,搜索和替换也是一个不错的选择。
补充:有人提到可以用as
来解决风格1中从some_module
切换到some_other_module
的问题。我忘了提的是,通常我们会决定在当前模块中实现some_identifier
,这会让创建一个等效的some_module
容器变得有点尴尬。
9 个回答
我更喜欢先使用 import X
,然后尽量用 X.a
。
不过在一些像Django这样的大框架中,情况就不一样了。这些框架里的模块名字通常很长,而且它们的例子里都说要用 from django.conf import settings
,这样可以省去到处写 django.conf.settings.DEBUG
的麻烦。
如果模块名字很复杂,那我就会例外,直接用 from X.Y.Z import a
。
有了下面这种写法:
import some_other_module as some_module
所以关于第二种风格的可维护性这个说法就不太适用了。
我个人比较喜欢用第一种风格。通常在一个普通的Python程序中,我发现我只会明确提到导入的包名几次。其他时候都是在用对象的方法,而这些方法当然不需要提到导入的包。
这两种情况都有用,所以我觉得这不是一个非此即彼的问题。
我会考虑在以下情况下使用 import x,y,z
来导入模块:
要导入的东西数量比较少。
导入的函数的用途很明显,即使不提模块名。如果这些名字比较普通,可能会和其他的名字冲突,而且信息量不大。比如,看到
remove
这个名字并不能告诉你太多,但os.remove
可能会让你知道你在处理文件。名字之间没有冲突。这个点比上面更重要。绝对不要做这样的事情:
from os import open
import module [as renamed_module]
的好处是,它能给你更多关于你在调用什么的上下文信息。不过,它的缺点是,如果模块本身没有提供更多信息,这样会显得有点杂乱,而且性能稍微差一点(需要查找两次,而不是一次)。
不过在测试的时候,这种方式也有优势(比如,可以用一个模拟对象替代 os.open,而不需要更改每个模块),在使用可变模块时应该使用这种方式,例如:
import config
config.dburl = 'sqlite:///test.db'
如果不确定的话,我总是会选择 import module
这种风格。