Python中的好或坏练习:在文件中间导入

时间:2009-07-27 14:53:25

标签: python python-import

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

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

import只应位于模块的第一部分。

示例:

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

请证明您的答案是合理的,并添加指向PEP或相关来源的链接

9 个答案:

答案 0 :(得分:55)

PEP 8权威地声明:

  

进口总是放在首位   文件,就在任何模块之后         注释和文档字符串,以及模块全局和常量之前。

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

答案 1 :(得分:17)

2001年在Python邮件列表上对该主题进行了详细讨论:

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

答案 2 :(得分:15)

其他人已经提到了PEP,但也注意在关键代码中间有导入语句。至少在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  

答案 3 :(得分:11)

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

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

答案 4 :(得分:8)

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

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

def detect(self):
    import foobar

如果此方法正常,则该工具可用。然后在同一模块中可能需要foobar模块,因此您必须在功能级别范围内再次导入它。显然,如果它是在模块级别导入的,那么事情会完全爆炸。

答案 5 :(得分:7)

在文件开头将所有导入分组在一起被视为“Good Form”。

  

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

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

答案 6 :(得分:6)

95%的情况下,您应该将所有导入放在文件的顶部。您可能希望执行函数本地导入的一种情况是,为了避免循环导入,必须执行此操作。假设foo.py导入bar.py,bar.py中的函数需要从foo.py导入一些东西。如果将所有导入放在顶部,则导入依赖于尚未编译的信息的文件时可能会出现意外问题。在这种情况下,使用函数本地导入可以允许代码在导入其他模块之前推迟其代码完全编译,并调用相关函数。

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

首先,而不是

from prerequisite import foo

直接导入先决条件,稍后将其称为prerequisite.foo。通过提高代码透明度,增加的详细程度可以自行恢复。

或者,(或与上述相结合)如果你的导入和它正在使用的地方之间真的有这么长的距离,那么你的模块可能太大了。没有其他任何用途的导入需求可能表明您的代码可以被重构为更易于管理的大块。

答案 7 :(得分:2)

PEP8

  

进口总是放在首位   文件,就在任何模块之后         注释和文档字符串,以及模块全局和常量之前。

进口scopped是不错的做法。因此导入仅适用于您在其中使用的函数。

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

答案 8 :(得分:2)

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