相关问题:
如果一个import
语句在函数内部,一旦函数退出,它占用的内存会被回收吗?如果是,那么回收的时间是确定性的(甚至是-ish)吗?
def func():
import os
...
# function about to exit; will memory occupied by `os` be freed?
如果有人知道关于micropython
这个话题的行为,加分。
相关问题:
如果一个import
语句在函数内部,一旦函数退出,它占用的内存会被回收吗?如果是,那么回收的时间是确定性的(甚至是-ish)吗?
def func():
import os
...
# function about to exit; will memory occupied by `os` be freed?
如果有人知道关于micropython
这个话题的行为,加分。
第一次导入执行模块中的代码。它创建模块对象的属性。每个后续导入仅引用第一次导入创建的模块对象。
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。
其次,@BlackJack 根据 Python 语义写的内容,“import”语句将模块引用添加到sys.modules
,仅此一项就可以防止模块对象被垃圾收集。
您可以尝试这样做del sys.modules["some_module"]
,但不能保证模块占用的所有内存都会被回收。(这个问题之前出现过,但我不记得它的当前状态,例如字节码对象是否可以被垃圾收集)。
如果是,那么回收的时间是确定性的(甚至是-ish)吗?
在 MicroPython 中,“回收时间”肯定是不确定的,因为它使用纯粹的垃圾收集方案,没有引用计数。这意味着任何消耗资源的对象(文件、套接字)都应该显式关闭。
否则,函数级导入在 Python 中是有效且有用的习惯用法,在 MicroPython 中尤其有用。只有在命中特定的代码路径时,它才允许导入某些模块。例如,如果用户从不调用某个函数,则不会导入模块,从而为用户在此特定应用程序/调用中需要更多的任务节省更多内存。