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()

当前回答

Putting the import statement inside of a function can prevent circular dependencies. For example, if you have 2 modules, X.py and Y.py, and they both need to import each other, this will cause a circular dependency when you import one of the modules causing an infinite loop. If you move the import statement in one of the modules then it won't try to import the other module till the function is called, and that module will already be imported, so no infinite loop. Read here for more - effbot.org/zone/import-confusion.htm

其他回答

模块导入非常快,但不是即时的。这意味着:

将导入放在模块的顶部是可以的,因为这是一个微不足道的成本,只需要支付一次。 将导入放在函数中会导致对该函数的调用花费更长的时间。

所以如果你关心效率,把进口放在最上面。只有在分析显示有帮助的情况下,才将它们移动到函数中(您进行了分析,以查看哪里可以最好地提高性能,对吗??)


我所见过的执行惰性导入的最佳理由是:

可选的库支持。如果您的代码有多个使用不同库的路径,如果没有安装可选库,请不要中断。 在插件的__init__.py中,该插件可能被导入,但实际上没有使用。例如Bazaar插件,它们使用bzrlib的惰性加载框架。

Curt提出了一个很好的观点:第二个版本更清晰,并且会在加载时失败,而不是在加载后失败,而且出乎意料。

通常我不担心加载模块的效率,因为它(a)非常快,(b)大多数只发生在启动时。

如果你不得不在意想不到的时候加载重量级模块,使用__import__函数动态加载它们可能更有意义,并确保捕获ImportError异常,并以合理的方式处理它们。

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

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

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

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

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

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

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.

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

这是一个引人入胜的讨论。和许多人一样,我从未考虑过这个话题。我不得不在函数中导入,因为我想在我的一个库中使用Django ORM。在导入我的模型类之前,我不得不调用django.setup(),因为这是在文件的顶部,它被拖到完全非django库代码中,因为IoC注入器结构。

我稍微改了一下,最后把django.setup()放在了单例构造函数中,并把相关的导入放在了每个类方法的顶部。现在这运行得很好,但让我感到不安,因为导入不在顶部,而且我开始担心导入的额外时间。然后我来到这里,怀着极大的兴趣阅读了大家对此的看法。

我有很长的c++背景,现在使用Python/Cython。我对此的看法是,为什么不把导入放在函数中,除非它会导致一个概要瓶颈。这就像在你需要变量之前为它们声明空间一样。问题是我有数千行代码,所有的导入都在顶部!所以我想从现在开始,当我有时间的时候,我会在这里和那里改变奇怪的文件。