导入语句应该始终位于模块的顶部吗?

2024-06-01 01:44:26 发布

您现在位置:Python中文网/ 问答频道 /正文

PEP 08状态:

Imports are always put at the top of the file, just after any module comments and docstrings, and before module globals and constants.

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

这不是:

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

Tags: andthefromimportselfdatetimeobjectdef
3条回答

我采用的做法是将所有导入放到使用它们的函数中,而不是放在模块的顶部。

我得到的好处是能够更可靠地重构。当我将一个函数从一个模块移到另一个模块时,我知道该函数将继续完整地处理它的所有遗留测试。如果我将导入放在模块的顶部,当我移动一个函数时,我会发现我最终花费了大量时间来完成新模块的导入并将其最小化。重构的IDE可能会使这变得不相关。

有一个速度惩罚,如其他地方提到的。我在申请表中对这一点进行了衡量,发现这对我的目的来说微不足道。

它也很高兴能够看到所有模块的依赖关系,而不诉诸于搜索(如grep)。但是,我关心模块依赖性的原因通常是因为我正在安装、重构或移动包含多个文件的整个系统,而不仅仅是单个模块。在这种情况下,我无论如何都要执行全局搜索,以确保具有系统级依赖项。因此,我还没有找到全球进口来帮助我在实践中理解一个体系。

我通常将sys的导入放在if __name__=='__main__'检查中,然后将参数(如sys.argv[1:])传递给main()函数。这允许我在未导入sys的上下文中使用main

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

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

所以如果你关心效率,就把进口放在首位。只有当您的配置文件显示有帮助时,才将它们移到函数中(您使用了profile来查看哪里最适合提高性能,对吗?)


我看到执行惰性导入的最佳原因是:

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

将import语句放在函数中可以防止循环依赖。 例如,如果您有两个模块X.py和Y.py,并且它们都需要彼此导入,那么当您导入其中一个模块时,这将导致循环依赖,从而导致无限循环。如果在其中一个模块中移动import语句,则在调用该函数之前它不会尝试导入另一个模块,并且该模块已经被导入,因此没有无限循环。阅读此处了解更多-effbot.org/zone/import-confusion.htm

相关问题 更多 >