代码之家  ›  专栏  ›  技术社区  ›  Bob

在函数内导入:函数退出时是否回收内存?

  •  3
  • Bob  · 技术社区  · 7 年前

    链接问题:

    如果 import 语句位于函数内部,一旦函数退出,它占用的内存会被回收吗?如果是,回收的时间是否确定(甚至 )?

    def func():
        import os
        ...
        # function about to exit; will memory occupied by `os` be freed?
    

    micropython

    2 回复  |  直到 7 年前
        1
  •  3
  •   BlackJack    7 年前

    第一次导入执行模块中的代码。它创建模块对象的属性。每个后续导入仅引用第一次导入创建的模块对象。

    Python中的模块对象实际上是单例的。为了实现这一点,Python实现必须在第一次导入后保留唯一的模块实例,而不管模块绑定到哪个名称。如果它被绑定到一个名称无论如何,也有进口的形式 from some_module import some_name

    因此,没有回收内存。

    不知道Micropython,但如果它在这里的语义发生如此剧烈的变化,我会感到惊讶。你可以自己测试一下:

    一些_模块。py:

    value = 0
    

    some\u other\u模块。py:

    def f():
        import some_module
        some_module.value += 1
        print(some_module.value)
    
    f()
    f()
    

    这应该打印数字1和2。

        2
  •  0
  •   pfalcon    7 年前

    为了支持@BlackJack编写的内容,根据Python语义,“import”语句将模块引用添加到 sys.modules ,这本身就可以防止模块对象被垃圾收集。

    你可以试着做 del sys.modules["some_module"]

    如果是,回收的时间是确定的(甚至是确定的)?

    在MicroPython中,“回收时间”保证是不确定的,因为它使用纯垃圾收集方案,没有引用计数。这意味着任何资源消耗对象(文件、套接字)都应该显式关闭。

    否则,函数级导入在Python中是有效和有用的习惯用法,在MicroPython中尤其有用。它只允许在命中特定代码路径时导入某些模块。E、 g.如果用户从不调用某些函数,则不会导入模块,从而为用户在该特定应用程序/调用中需要的任务节省更多内存。