Python中的好坏做法:在文件中间导入

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

在模块中间导入该方法或模块是否被认为是正确的?

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

例:

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

请certificate您的答案,并添加PEP或相关来源的链接

PEP8权威地表示:

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

PEP 8应该是任何“内部”风格指南的基础,因为它总结了Python核心团队发现的最有效的风格,总体上(当然也有个别的异议,就像任何其他语言一样, BDFL同意PEP 8)。

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

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

其他人已经提到了PEP,但是也要注意在关键代码中间没有import声明。 至less在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 

如果导入的模块不经常使用并且导入昂贵,那么中间导入就OK了。

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

在文件开始时将所有import分组在一起被认为是“良好的forms”。

模块可以导入其他模块。 习惯上,不要求在模块(或脚本)的开始部分放置所有的导入语句。 导入的模块名称被放置在导入模块的全局符号表中。

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

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

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

 def detect(self): import foobar 

如果这工作正常,该工具是可用的。 然后在相同的模块中可能需要foobar模块,所以您必须在函数级范围内再次导入它。 很显然,如果在模块级别导入,事情会完全崩溃。

95%的时间,你应该把所有的import放在文件的顶部。 一种情况,你可能想做一个函数本地导入,如果你必须这样做,以避免循环导入。 说foo.pyimportbar.py,bar.py中的函数需要从foo.py中导入。 如果你把所有的导入放在最前面,你可能会遇到意想不到的问题,导入依赖尚未编译的信息的文件。 在这种情况下,使用本地导入function可以让您的代码延迟导入其他模块,直到其代码被完全编译,然后调用相关函数。

然而,看起来你的用例更多的是清楚foo()是从哪里来的。 在这种情况下,我更喜欢两件事情之一:

首先,而不是

 from prerequisite import foo 

直接导入先决条件,以后再作为先决条件.foo。 增加的冗长性通过增加代码透明度而得到回报。

或者,(或者与上述结合),如果你的导入和它所使用的地方之间的距离真的很长,可能是你的模块太大了。 没有其他任何东西使用的导入的需要可能是一个地方,你的代码可以被重构成一个更可pipe理的大小的块的迹象。

PEP8 :

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

import货物是不好的做法。 所以导入只适用于你使用它的函数。

我认为这个代码会更易于阅读,尽pipe如果在块的顶部将它们组合在一起,或者在文件的顶部全局的话。

那么,我认为这是一个很好的做法,在文件开始时将所有的input组合在一起,因为如果想知道哪些库被加载