在速度和内存效率方面,在函数内部导入 Python 模块和/或函数的优缺点是什么?
每次运行函数时是否重新导入,或者无论函数是否运行,都可能只在开始时重新导入一次?
在速度和内存效率方面,在函数内部导入 Python 模块和/或函数的优缺点是什么?
每次运行函数时是否重新导入,或者无论函数是否运行,都可能只在开始时重新导入一次?
每次运行函数时都会重新导入吗?
不; 或者更确切地说,Python 模块在每次导入时都会被缓存,因此导入第二次(或第三次或第四次......)实际上并不会强制它们再次完成整个导入过程。1
无论函数是否运行,它是否在开始时导入一次?
至于好处:这取决于,我猜。如果您可能只很少运行一个函数并且不需要在其他任何地方导入模块,那么只在该函数中导入它可能是有益的。或者,如果存在名称冲突或其他原因,您不希望模块中的模块或符号随处可用,您可能只想在特定函数中导入它。(当然,总是from my_module import my_function as f
有这些情况。)
在一般实践中,它可能没有那么有益。事实上,大多数 Python 风格指南都鼓励程序员将所有导入放在模块文件的开头。
第一次import goo
从任何地方(函数内部或外部)goo.py
(或其他可导入形式)加载并sys.modules['goo']
设置为由此构建的模块对象。在程序的同一运行中(再次,无论是在函数内部还是外部)中的任何未来导入都只需在适当的范围内查找sys.modules['goo']
并将其绑定到barename goo
。dict 查找和名称绑定是非常快速的操作。
假设第一个import
在程序运行时完全摊销,将“适当范围”设置为模块级意味着每次使用goo.this
,goo.that
等都是两个 dict 查找——一个用于goo
属性名称,一个用于属性名称。将其设置为“函数级别”会为每次运行函数支付一个额外的局部变量设置(甚至比字典查找部分更快!),但为每个goo.this
(等)访问,基本上将此类查找所需的时间减半。
我们以一种或另一种方式谈论几纳秒,所以这几乎不是值得优化的。一个函数内部的一个潜在的实质性优势是,import
在给定的程序运行中可能根本不需要该函数,例如,该函数通常处理错误、异常和罕见情况;如果是这种情况,任何不需要该功能的运行甚至都不会执行导入(这节省了微秒,而不仅仅是纳秒),只有确实需要该功能的运行才会支付(适度但可衡量的)价格。
它仍然是一种仅在非常极端的情况下才值得的优化,在尝试以这种方式挤出微秒之前,我会考虑许多其他优化。
它在函数第一次执行时导入一次。
优点:
缺点:
我是否可以笼统地建议,而不是问,“X 会提高我的表现吗?” 您使用分析来确定您的程序实际将时间花在哪里,然后根据您将获得最大收益的地方应用优化?
然后您可以使用分析来确保您的优化实际上也使您受益。
在函数内部导入将有效地导入模块一次..在函数第一次运行时。
无论是在顶部导入还是在函数运行时导入,它都应该以同样快的速度导入。这通常不是导入 def 的好理由。优点?如果不调用该函数,它将不会被导入。如果您的模块只要求用户在使用您的特定功能时安装某个模块,这实际上是一个合理的理由...
如果这不是他这样做的原因,那几乎可以肯定这是一个令人讨厌的想法。
它在第一次调用该函数时导入一次。
如果我在导入的模块中有一个很少使用并且是唯一需要导入的函数,我可以想象这样做。虽然看起来有点牵强...