在Python中,函数内导入会发生什么?
在一个函数里面导入Python模块或函数,有什么好处和坏处?特别是从速度和内存的角度来看。
每次运行这个函数的时候,它会重新导入吗?还是说只在一开始导入一次,不管这个函数有没有被运行?
6 个回答
这个导入操作只在函数第一次执行的时候进行一次。
优点:
- 导入的模块和它们被使用的函数是相关的
- 在包里面移动函数的时候很方便
缺点:
- 看不出这个模块可能依赖哪些其他模块
第一次使用 import goo
时,不管是在函数里面还是外面,goo.py
这个文件就会被加载,同时 sys.modules['goo']
会被设置为这个模块的对象。之后在程序运行期间的任何地方再用 import goo
,都会直接查找 sys.modules['goo']
,然后把它绑定到名字 goo
上,这个过程非常快。
假设第一次的 import
在程序运行时已经被“摊销”掉了,模块级别的“适当范围”意味着每次使用 goo.this
、goo.that
等时,需要进行两次查找:一次是查找 goo
,另一次是查找属性名。而如果是在函数级别,只需多设置一个局部变量(这个过程比查找字典还快!),但每次访问 goo.this
时就省去了一次字典查找,实际上是把查找时间减半了。
不过,这里说的时间差别只是几纳秒,所以其实并不是特别值得去优化。把 import
放在函数内部的一个潜在好处是,如果这个函数在某次程序运行中根本不需要,比如处理错误、异常和一些罕见情况的函数;那么在不需要这个功能的情况下,程序就不会执行这个导入(这节省的时间是微秒级别,而不仅仅是纳秒),只有需要这个功能的运行才会付出这个(虽然不算太高但可以测量的)代价。
总的来说,这种优化只有在非常极端的情况下才值得考虑,而且在尝试通过这种方式节省微秒之前,还有很多其他的优化方法可以考虑。
每次运行这个函数的时候,它会重新导入吗?
不会;或者说,Python 的模块在第一次导入后会被缓存,所以第二次(或者第三次、第四次……)导入的时候,并不会再走一遍完整的导入流程。1
它是在一开始就导入一次,不管函数有没有运行?
至于好处嘛,这要看情况。如果你很少运行这个函数,并且不需要在其他地方导入这个模块,那么在这个函数里导入可能会更好。或者如果有名字冲突,或者其他原因不想让这个模块或模块里的符号在任何地方都可用,你可能只想在特定的函数里导入它。(当然,对于这种情况,你总是可以用 from my_module import my_function as f
。)
一般来说,这样做可能并没有太大好处。实际上,大多数 Python 风格指南都建议程序员把所有的导入放在模块文件的开头。