在Python中,当您在函数内部导入时会发生什么? [重复]

问题描述 投票:132回答:6

这个问题在这里已有答案:

在速度和内存效率方面,在函数内导入Python模块和/或函数的优缺点是什么?

是否每次运行该函数时重新导入,或者可能只在开始时重新导入一次,无论函数是否运行?

python python-import
6个回答
117
投票

每次运行该功能时是否重新导入?

没有;或者更确切地说,Python模块在每次导入时基本上都被缓存,因此导入第二个(或第三个或第四个......)时间实际上并不会强制它们再次完成整个导入过程。 1

无论函数是否运行,它都会在开头导入一次吗?

不,只有在执行该功能时才导入它。 23

至于好处:这取决于我猜。如果您可能很少运行函数并且不需要在其他任何地方导入模块,那么仅在该函数中导入它可能是有益的。或者,如果存在名称冲突或其他原因,您不希望模块中的模块或符号随处可用,您可能只想在特定函数中导入它。 (当然,这些案件总是有from my_module import my_function as f。)

在一般实践中,它可能没那么有益。实际上,大多数Python样式指南都鼓励程序员将所有导入放在模块文件的开头。


37
投票

第一次从任何地方(函数内部或外部)import goo,加载goo.py(或其他可导入的形式),并将sys.modules['goo']设置为这样构建的模块对象。在程序的同一次运行中的任何未来导入(再次,无论是在函数内部还是外部)只需查找sys.modules['goo']并将其绑定到适当范围内的barename goo。 dict查找和名称绑定是非常快速的操作。

假设第一个import在程序运行中完全摊销,将“适当范围”设置为模块级意味着每次使用goo.thisgoo.that等都是两个dict查找 - 一个用于goo,一个用于属性名称。让它成为“功能级别”每次运行函数都会支付一个额外的局部变量设置(甚至比字典查找部分更快!)但是为每个goo.this保存一个dict查找(将其交换为局部变量查找,非常快) (等)访问,基本上减少了这种查找所花费的时间。

我们谈论的是几纳秒这样或那样,所以这几乎不值得进行优化。在一个函数中使用import的一个潜在的实质性优点是,在程序的给定运行中根本不需要该函数,例如,该函数通常处理错误,异常和罕见情况;如果是这种情况,任何不需要该功能的运行甚至都不会执行导入(这可以节省微秒,而不仅仅是纳秒),只有需要该功能才能支付(适度但可测量)价格的运行。

它仍然是一种在非常极端情况下值得的优化,并且在尝试以这种方式挤出微秒之前还有许多其他的考虑因素。


9
投票

它在第一次执行函数时导入一次。

优点:

  • 与他们使用的功能相关的导入
  • 易于移动包装周围的功能

缺点:

  • 看不出这个模块可能依赖的模块

5
投票

在函数内部导入将有效地导入模块一次..第一次运行该函数。

无论是在顶部导入还是在运行函数时,它都应该以同样的速度导入。这通常不是导入def的好理由。优点?如果没有调用该函数,它将不会被导入..这实际上是一个合理的理由,如果你的模块只需要用户安装某个模块,如果他们使用你的特定功能...

如果他不是因为你这样做,那几乎可以肯定是一个令人讨厌的想法。


3
投票

可能我总体上建议不要问“X会改善我的表现吗?”您使用分析来确定您的程序实际花费时间的位置,然后根据您将获得最大收益的位置应用优化?

然后,您可以使用分析来确保您的优化实际上也使您受益。


2
投票

它首次调用函数时导入一次。

如果我在导入的模块中有一个很少使用的函数并且是唯一需要导入的函数,我可以想象这样做。看起来相当牵强,但......

© www.soinside.com 2019 - 2024. All rights reserved.