'从X导入'与'导入X; X.a”

时间:2008-10-09 09:04:34

标签: python python-import maintainability duck-typing

我见过一些Python程序员相当一致地使用以下样式(我们称之为样式1):

import some_module
# Use some_module.some_identifier in various places.

为了支持这种风格,您可以引用"explicit is better than implicit"格言。我见过其他程序员使用这种风格(风格2):

from some_module import some_identifier
# Use some_identifier in various places.

我在样式2中看到的主要好处是可维护性 - 特别是对于duck typing理想我可能想要将some_module交换为some_other_module。我也觉得"readability counts"格言的风格2胜。虽然我倾向于不同意,但人们总是认为在使用第一种风格时,搜索和替换是一个很好的选择。

附录:有人指出,您可以使用as来解决样式1中从some_modulesome_other_module的切换。我忘了提及它决定在当前模块中实施some_identifier也很常见,这使得创建等效的some_module容器略显尴尬。

9 个答案:

答案 0 :(得分:5)

存在以下语法:

import some_other_module as some_module

样式2的可维护性参数不再相关。

我倾向于使用样式1.通常,我发现在典型的Python程序中我只显式引用了几次导入的包名。其他一切都是对象上的方法,当然不需要引用导入的包。

答案 1 :(得分:5)

这两种情况都有用,所以我不认为这是一个或两个问题。 我考虑在以下时间使用模块import x,y,z

  • 要导入的内容相当少

  • 当从模块名称中分离时,导入函数的目的是显而易见的。如果名称相当通用,他们可能会与其他人发生冲突,并告诉你很少。例如。看到remove告诉你很少,但os.remove可能暗示你正在处理文件。

  • 这些名字不会发生冲突。与上述类似,但更重要。 从不执行以下操作:

     from os import open
    

import module [as renamed_module]的优势在于它为您使用它时所调用的内容提供了更多的背景信息。它的缺点是,当模块没有真正提供更多信息时,这会更加混乱,并且性能稍差(2次查找而不是1次)。

然而,在测试时它也具有优势(例如,用模拟对象替换os.open,而不必更改每个模块),并且在使用可变模块时应该使用,例如

import config
config.dburl = 'sqlite:///test.db'

如果有疑问,我总是选择import module风格。

答案 2 :(得分:2)

我通常使用阈值来决定这一点。如果我想在some_module中使用很多东西,我会使用:

import some_module as sm
x = sm.whatever

如果我只需要一两件事:

from some_module import whatever
x = whatever

当然,假设我不需要来自whatever的{​​{1}}。

我倾向于在导入上使用some_other_module子句,以便我可以在将来轻松地减少输入替换另一个模块。

答案 3 :(得分:2)

我更喜欢import X,然后尽可能使用X.a

我的例外以Django这样的大框架中的深层嵌套模块为中心。他们的模块名称往往变得冗长,他们的示例都说from django.conf import settings,以免您在任何地方输入django.conf.settings.DEBUG

如果模块名称是深层嵌套的,那么例外是使用from X.Y.Z import a

答案 4 :(得分:1)

我发现了符号

from some_module import some_symbol

在大多数情况下效果最佳。此外,如果符号出现名称冲突,您可以使用:

from some_module import some_symbol as other_symbol

正如问题所述,它避免了一直重写模块名称,每次都有冒充错误的风险。我使用语法:

import  module [as other_module]

仅在两种情况下:

  1. 我使用了太多的模块函数/对象来导入它们
  2. 模块定义了一些可能在执行期间更改的符号

答案 5 :(得分:0)

我相信更新版本的Python(2.5+?必须检查我的事实......)你甚至可以这样做:

import some_other_module as some_module

所以你仍然可以使用样式1并稍后交换不同的模块。

我认为它通常会映射到您希望混淆命名空间的程度。你会在模块中使用一个或两个名字吗?或者所有这些(from x import *并非总体上不好,只是一般而言)?

答案 6 :(得分:0)

我个人尽量不要过多地使用我的命名空间,所以在大多数情况下我只是做

import module  

或     导入模块为mod

只有真正的差异才是我有一个单独使用过很多类的模块。如果我已经使用list类型进行子类化以在那里添加一些功能,我会使用

from SuperImprovedListOverloadedWithFeatures import NewLIst
nl = NewList()

答案 7 :(得分:0)

我倾向于只使用每个模块的几个成员,因此有很多

from john import cleese
from terry import jones, gilliam

在我的代码中。如果我希望使用大部分模块并且模块名称很短,我将导入整个模块(例如oswx)。如果存在名称冲突,我也会导入整个模块,或者我想提醒读者与该功能相关联的内容。

import michael
import sarah

import wave

gov_speech = wave.open(sarah.palin.speechfile)
parrot_sketch = wave.open(michael.palin.justresting)

(我可以使用from wave import open as wave_open,但我认为读者会更熟悉wave.open

答案 8 :(得分:0)