在函数内部导入Python模块和/或函数,在效率、速度和内存方面有哪些优点和缺点?

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


当前回答

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

无论您是在顶部导入它,还是在函数运行时导入它,它都应该导入得一样快。这通常不是一个在定义中导入的好理由。优点是什么?如果函数没有被调用,它将不会被导入。这实际上是一个合理的原因,如果你的模块只要求用户安装某个模块,如果他们使用你的特定功能…

如果这不是你做这件事的原因,那几乎可以肯定这是个恶心的主意。

其他回答

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

无论您是在顶部导入它,还是在函数运行时导入它,它都应该导入得一样快。这通常不是一个在定义中导入的好理由。优点是什么?如果函数没有被调用,它将不会被导入。这实际上是一个合理的原因,如果你的模块只要求用户安装某个模块,如果他们使用你的特定功能…

如果这不是你做这件事的原因,那几乎可以肯定这是个恶心的主意。

它是否在每次函数运行时都重新导入?

没有;或者说,Python模块在每次导入时本质上都是缓存的,因此第二次(或第三次,或第四次……)导入实际上并不会迫使它们再次经历整个导入过程。1

无论函数是否运行,它是否在开始时导入一次?

不,它只在函数执行时被导入。2、3

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

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

当你第一次从任何地方(函数内部或外部)导入goo时,goo.py(或其他可导入的形式)会被加载,并且sys. py会被加载。Modules ['goo']被设置为这样构建的模块对象。以后在程序运行的同一段时间内(同样,无论是在函数内部还是函数外部),只要查找sys. exe即可。模块['goo'],并将其绑定到适当范围内的假名goo。字典查找和名称绑定是非常快速的操作。

Assuming the very first import gets totally amortized over the program's run anyway, having the "appropriate scope" be module-level means each use of goo.this, goo.that, etc, is two dict lookups -- one for goo and one for the attribute name. Having it be "function level" pays one extra local-variable setting per run of the function (even faster than the dictionary lookup part!) but saves one dict lookup (exchanging it for a local-variable lookup, blazingly fast) for each goo.this (etc) access, basically halving the time such lookups take.

We're talking about a few nanoseconds one way or another, so it's hardly a worthwhile optimization. The one potentially substantial advantage of having the import within a function is when that function may well not be needed at all in a given run of the program, e.g., that function deals with errors, anomalies, and rare situations in general; if that's the case, any run that does not need the functionality will not even perform the import (and that's a saving of microseconds, not just nanoseconds), only runs that do need the functionality will pay the (modest but measurable) price.

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

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

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

我是否可以建议,一般来说,不要问“X会提高我的性能吗?”,而是使用分析来确定程序实际在哪些地方花费了时间,然后根据您将获得最大收益的地方应用优化?

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