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

In Python, what happens when you import inside of a function?

本问题已经有最佳答案,请猛点这里访问。

在函数内部导入一个python模块和/或函数的优点和缺点是什么,关于速度和内存的效率?

它是在每次运行函数时重新导入,还是在开始时只导入一次,不管函数是否运行?


Does it re-import every time the function is run?

不;或者更确切地说,每次导入python模块时,它们基本上都是缓存的,因此导入第二次(或第三次或第四次…)实际上并不强制它们再次执行整个导入过程。一

Does it import once at the beginning whether or not the function is run?

不,只有在执行函数时才导入。2, 3

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

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


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

假设第一个import在程序运行期间完全摊销,那么"适当范围"是模块级意味着每次使用goo.thisgoo.that等都是两个dict查找——一个用于goo,一个用于属性名。如果它是"函数级",则每次运行函数都要额外支付一个局部变量设置(甚至比字典查找部分更快!)但是为每个goo.this访问节省了一个dict查找(将其替换为局部变量查找,速度极快),基本上将这种查找所花费的时间减半。

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

这仍然是一个只有在非常极端的情况下才有价值的优化,在尝试以这种方式挤出微秒之前,还有许多其他的我会考虑的。


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

赞成的意见:

  • 与所用函数相关的导入
  • 易于在包中移动函数

欺骗:

  • 无法查看此模块可能依赖的模块


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

不管您是在顶部导入,还是在函数运行时导入,它都应该以同样快的速度导入。这通常不是导入def的好理由。赞成的意见?如果不调用函数,则不会导入它。如果您的模块只要求用户在使用您的特定功能时安装某个模块,那么这实际上是一个合理的原因…

如果这不是你这么做的原因,那几乎肯定是个糟糕的主意。


我可以建议大家不要问"X能提高我的表现吗?"您可以使用分析来确定您的程序实际花费的时间在哪里,然后根据您将从中获得最大好处的地方应用优化?

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


当第一次调用函数时,它导入一次。

我可以想象这样做,如果我在一个导入的模块中有一个函数,这个模块非常独立地使用,并且是唯一需要导入的模块。不过看起来有点牵强…