相关问题:
如果函数内部有一个import
语句,一旦函数退出,它所占用的内存是否会被回收?如果是,那么回收的时间是否确定(或者甚至 -ish )?
def func():
import os
...
# function about to exit; will memory occupied by `os` be freed?
如果有人了解micropython
关于此主题的行为,可以获得奖励积分。
答案 0 :(得分:3)
第一次导入执行模块中的代码。它创建模块对象的属性。每个后续导入仅引用第一次导入创建的模块对象。
Python中的模块对象实际上是单例。为了实现这一点,Python实现必须在第一次导入后保留唯一的模块实例,而不管模块绑定的名称如何。如果它被绑定到一个名称,因为还有from some_module import some_name
形式的导入。
所以不,内存没有被回收。
不知道Micropython,但如果它在这里彻底改变语义,我会感到惊讶。你可以自己测试一下:
some_module.py:
value = 0
some_other_module.py:
def f():
import some_module
some_module.value += 1
print(some_module.value)
f()
f()
这应该打印数字1和2.
答案 1 :(得分:0)
要了解@BlackJack所写的内容,根据Python语义,“import”语句会将模块引用添加到sys.modules
,这样就可以防止模块对象被垃圾回收。
您可以尝试执行del sys.modules["some_module"]
,但无法保证模块占用的所有内存都将被回收。 (之前出现过这个问题,但我不记得它的当前状态,例如,如果字节码对象可以被垃圾收集)。
如果是,那么回收的时间是否确定(或甚至是-ish)?
在MicroPython中,“回收时间”肯定是不确定的,因为它使用纯粹的垃圾收集方案,没有引用计数。这意味着应该显式关闭任何耗费资源的对象(文件,套接字)。
否则,函数级导入在Python中是有效且有用的习惯用法,在MicroPython中尤其有用。它只允许在命中特定代码路径时导入某些模块。例如。如果用户从不调用某个函数,则不会导入模块,为用户在此特定应用程序/调用中需要的任务节省更多内存。