64

假设我有一个相对较长的模块,但只需要一个外部模块或方法一次。

在模块中间导入该方法或模块是否被认为可以?

或者应该import只在模块的第一部分。

例子:

import string, pythis, pythat
...
...
...
...
def func():
     blah
     blah 
     blah
     from pysomething import foo
     foo()
     etc
     etc 
     etc
...
...
...

请证明您的回答并添加指向PEP或相关来源的链接

4

9 回答 9

65

PEP 8权威性地指出:

导入总是放在文件的顶部,就在任何模块注释和文档字符串之后,模块全局变量和常量之前。

PEP 8 应该是任何“内部”风格指南的基础,因为它总结了核心 Python 团队发现的最有效的风格,总体而言(当然,与任何其他语言一样,个人持不同意见,但达成共识和 BDFL 就 PEP 8 达成一致)。

于 2009-07-27T14:59:05.237 回答
28

在 2001 年的 Python 邮件列表上有关于这个话题的详细讨论:

https://mail.python.org/pipermail/python-list/2001-July/071567.html

以下是该线程中讨论的一些原因。来自 Peter Hansen,以下是不在文件顶部全部导入的三个原因:

在函数中导入的可能原因:

  1. 可读性:如果只在一个函数中需要导入并且这不太可能改变,那么只把它放在那里可能会更清晰、更清晰。

  2. 启动时间:如果您在函数定义之外没有导入,那么当您的模块首次被另一个模块导入时,它不会执行,但只有在调用其中一个函数时才会执行。这会延迟导入的开销(或者如果函数可能永远不会被调用,则可以避免它)。

  3. 总有一个比我们迄今为止所想的原因多一个的原因。

刚刚范罗苏姆附和了第四个:

  1. 开销:如果模块导入了很多模块,并且很有可能只有少数模块会被实际使用。这类似于“启动时间”的原因,但更进一步。如果使用您的模块的脚本仅使用一小部分功能,则可以节省相当多的时间,特别是如果可以避免的导入也导入了很多模块。

提供第五个是因为本地进口是避免循环进口问题的一种方式。

请随意阅读该主题以进行完整讨论。

于 2009-07-27T15:02:08.773 回答
20

其他人都已经提到了 PEP,但也要注意不要在关键代码中间有 import 语句。至少在 Python 2.6 下,当函数具有 import 语句时,还需要更多的字节码指令。

>>> def f():
    from time import time
    print time()

>>> dis.dis(f)
  2           0 LOAD_CONST               1 (-1)
              3 LOAD_CONST               2 (('time',))
              6 IMPORT_NAME              0 (time)
              9 IMPORT_FROM              0 (time)
             12 STORE_FAST               0 (time)
             15 POP_TOP             

  3          16 LOAD_FAST                0 (time)
             19 CALL_FUNCTION            0
             22 PRINT_ITEM          
             23 PRINT_NEWLINE       
             24 LOAD_CONST               0 (None)
             27 RETURN_VALUE

>>> def g():
    print time()

>>> dis.dis(g)
  2           0 LOAD_GLOBAL              0 (time)
              3 CALL_FUNCTION            0
              6 PRINT_ITEM          
              7 PRINT_NEWLINE       
              8 LOAD_CONST               0 (None)
             11 RETURN_VALUE  
于 2009-07-27T16:27:29.433 回答
12

如果导入的模块不经常使用并且导入成本高,中间导入就可以了。

否则,遵循 Alex Martelli 的建议是否明智。

于 2009-07-27T14:59:13.913 回答
8

这通常被认为是不好的做法,但有时它是不可避免的(比如当你必须避免循环导入时)。

必要时的一个例子:我使用Waf来构建我们所有的代码。系统分为工具,每个工具都在自己的模块中实现。每个工具模块都可以实现一种detect()方法来检测是否存在先决条件。其中之一的示例可以执行以下操作:

def detect(self):
    import foobar

如果这工作正常,则该工具可用。然后稍后在同一模块中foobar可能需要该模块,因此您必须在功能级别范围内再次导入它。显然,如果它是在模块级别导入的,事情就会彻底崩溃。

于 2009-07-27T14:57:40.233 回答
7

在文件开头将所有导入组合在一起被认为是“良好的形式”。

模块可以导入其他模块。将所有导入语句放在模块(或脚本,就此而言)的开头是习惯但不是必需的。导入的模块名称放置在导入模块的全局符号表中。

从这里:http ://docs.python.org/tutorial/modules.html

于 2009-07-27T14:57:15.973 回答
6

95% 的情况下,您应该将所有导入文件放在文件的顶部。您可能想要进行函数本地导入的一种情况是,如果您必须这样做以避免循环导入。说 foo.py 导入 bar.py,bar.py 中的一个函数需要从 foo.py 中导入一些东西。如果将所有导入都放在顶部,则导入依赖于尚未编译的信息的文件可能会遇到意外问题。在这种情况下,有一个函数本地导入可以让你的代码推迟导入另一个模块,直到它的代码被完全编译,然后你调用相关的函数。

但是,看起来您的用例更多的是要明确 foo() 的来源。在这种情况下,我更喜欢以下两件事之一:

首先,而不是

from prerequisite import foo

直接导入先决条件,稍后将其称为prerequisite.foo。通过增加代码透明度,增加的冗长性得到了回报。

或者,(或结合上述)如果你的导入和使用它的地方之间的距离真的很长,那么可能是你的模块太大了。不需要其他任何东西使用的导入可能表明您的代码可以被重构为更易于管理的块的位置。

于 2009-07-27T15:30:42.857 回答
3

PEP8

导入总是放在文件的顶部,就在任何模块注释和文档字符串之后,模块全局变量和常量之前。

确定进口范围并不是一个坏习惯。这样导入仅适用于您使用它的功能。

我认为,如果导入在块的顶部组合在一起,或者如果您希望它全局位于文件的顶部,我认为代码会更具可读性。

于 2009-07-27T14:59:36.003 回答
2

好吧,我认为在文件开头将所有导入组合在一起是一个好习惯,因为如果想知道加载了哪些库,每个人都知道在哪里看

于 2009-07-27T15:00:08.247 回答