PEP 8规定:

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

然而,如果我导入的类/方法/函数只在很少的情况下使用,那么在需要时进行导入肯定会更有效吗?

这不是:

class SomeClass(object):

    def not_often_called(self)
        from datetime import datetime
        self.datetime = datetime.now()

比这更有效率?

from datetime import datetime

class SomeClass(object):

    def not_often_called(self)
        self.datetime = datetime.now()

当前回答

I do not aspire to provide complete answer, because others have already done this very well. I just want to mention one use case when I find especially useful to import modules inside functions. My application uses python packages and modules stored in certain location as plugins. During application startup, the application walks through all the modules in the location and imports them, then it looks inside the modules and if it finds some mounting points for the plugins (in my case it is a subclass of a certain base class having a unique ID) it registers them. The number of plugins is large (now dozens, but maybe hundreds in the future) and each of them is used quite rarely. Having imports of third party libraries at the top of my plugin modules was a bit penalty during application startup. Especially some thirdparty libraries are heavy to import (e.g. import of plotly even tries to connect to internet and download something which was adding about one second to startup). By optimizing imports (calling them only in the functions where they are used) in the plugins I managed to shrink the startup from 10 seconds to some 2 seconds. That is a big difference for my users.

所以我的答案是否定的,不要总是把导入放在模块的顶部。

其他回答

有趣的是,到目前为止,没有一个回答提到并行处理,当序列化的函数代码被推到其他核心时,可能需要将导入放在函数中,例如在ipyparallel的情况下。

大多数情况下,这对于清晰和明智的做法是有用的,但并不总是如此。下面是模块导入可能存在于其他地方的两个例子。

首先,你可以有一个这样的单元测试模块:

if __name__ == '__main__':
    import foo
    aa = foo.xyz()         # initiate something for the test

其次,您可能需要在运行时有条件地导入一些不同的模块。

if [condition]:
    import foo as plugin_api
else:
    import bar as plugin_api
xx = plugin_api.Plugin()
[...]

在其他情况下,您可能会在代码的其他部分导入。

除了已经给出的优秀答案之外,值得注意的是导入的位置不仅仅是风格的问题。有时,模块具有需要首先导入或初始化的隐式依赖项,而顶层导入可能会导致违反所需的执行顺序。

这个问题经常出现在Apache Spark的Python API中,在导入任何pyspark包或模块之前,你需要初始化SparkContext。最好将pyspark导入放在保证SparkContext可用的范围内。

虽然PEP鼓励在模块顶部导入,但在其他级别导入并不会出错。这表明进口应该在顶部,但也有例外。

在使用模块时加载模块是一种微优化。导入缓慢的代码可以在以后进行优化,如果这会产生相当大的差异的话。

不过,您可以在尽可能靠近顶部的位置引入标志,以便有条件地导入,允许用户使用配置导入所需的模块,同时仍然立即导入所有内容。

尽快导入意味着如果任何导入(或导入的导入)缺失或有语法错误,程序将失败。如果所有导入都发生在所有模块的顶部,则python分两步工作。编译。运行。

内置模块可以在任何导入它们的地方工作,因为它们设计得很好。您编写的模块应该是相同的。将导入移动到顶部或它们的第一次使用位置有助于确保没有副作用,并且代码正在注入依赖项。

无论您是否将导入放在顶部,当导入放在顶部时,代码都应该仍然可以工作。所以从立即导入开始,然后根据需要进行优化。

以下是对这个问题的最新答案总结 而且 相关的 的问题。

PEP 8 recommends putting imports at the top. It's often more convenient to get ImportErrors when you first run your program rather than when your program first calls your function. Putting imports in the function scope can help avoid issues with circular imports. Putting imports in the function scope helps keep maintain a clean module namespace, so that it does not appear among tab-completion suggestions. Start-up time: imports in a function won't run until (if) that function is called. Might get significant with heavy-weight libraries. Even though import statements are super fast on subsequent runs, they still incur a speed penalty which can be significant if the function is trivial but frequently in use. Imports under the __name__ == "__main__" guard seem very reasonable. Refactoring might be easier if the imports are located in the function where they're used (facilitates moving it to another module). It can also be argued that this is good for readability. However, most would argue the contrary, i.e. Imports at the top enhance readability, since you can see all your dependencies at a glance. It seems unclear if dynamic or conditional imports favour one style over another.