You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何让Python模块每次导入时都生成新对象?

解决每次调用call_foo()都输出6的问题

这问题我太熟悉了!Python里模块默认是单例模式的——第一次导入后,模块对象会被缓存到sys.modules字典里,后续所有的import操作都会直接复用这个缓存好的对象。所以你现在每次调用call_foo(),都是在修改同一个foo模块实例里的a值,自然会越来越大。

要实现每次调用都让import foo像创建新对象一样,有两种实用的方法:

方法一:用importlib.reload()重载模块

直接在每次调用时重新加载foo模块,重置它的内部状态:

# bar.py
import importlib
import foo  # 先导入一次基础模块

def call_foo():
    importlib.reload(foo)  # 关键:每次调用都重新加载foo
    foo.a += 1
    print(foo.a)

call_foo()  # 输出6
call_foo()  # 输出6

reload()会重新执行foo.py的代码,把模块内的变量重置为初始值,这样每次调用时foo.a都会回到5,加1后自然就是6。

方法二:删除sys.modules中的模块缓存

先把缓存的foo模块从sys.modules里删掉,这样下次import就会重新创建全新的模块对象:

# bar.py
import sys

def call_foo():
    # 移除已缓存的foo模块(如果存在)
    if 'foo' in sys.modules:
        del sys.modules['foo']
    import foo  # 此时会重新导入,生成新的模块实例
    foo.a += 1
    print(foo.a)

call_foo()  # 输出6
call_foo()  # 输出6

sys.modules是Python用来存储所有已导入模块的缓存字典,删除对应的键后,import foo会重新执行模块代码,相当于每次都创建了一个新的foo模块对象,a的初始值始终是5。

注意事项

  • 这两种方法都适合简单场景,如果你的foo模块有复杂的初始化逻辑(比如打开文件、建立数据库连接),频繁重载/重新导入可能会引发副作用,需要谨慎使用。
  • 生产环境中尽量避免频繁操作模块缓存,除非确实有明确的需求,否则可能影响性能和代码的可维护性。

内容的提问来源于stack exchange,提问作者Herel Adrastel

火山引擎 最新活动