You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

动态加载类与import加载类的类识别问题

回答

嘿,这个问题我之前也踩过坑,核心原因其实是同一个Python文件被当成了两个完全独立的模块,导致对应的类对象也不是同一个实例。

为什么会出现这种情况?

当你用from test import Test的时候,Python会把test.py加载成一个模块,并存到sys.modules的缓存里,键名是'test'。而你后面用importlib.util.spec_from_file_location加载时,虽然指定了模块名也是'test',但Python并没有复用缓存里已有的模块,而是重新读取文件、创建了一个全新的模块对象——里面的Test类自然也是一个全新的类,和你之前import的那个Test完全不是同一个对象。

你可以加两行代码验证这个结论:

import sys
print(sys.modules['test'] is module)  # 会输出False
print(Test is loaded_test)  # 也会输出False

既然两个Test是不同的类,那isinstance(t, loaded_test)返回False就不奇怪了,毕竟t是第一个Test类的实例。

怎么解决这个问题?

根据你的实际需求,有几种靠谱的方案:

1. 优先复用已加载的模块

如果不需要重新加载文件内容,直接用sys.modules缓存里的模块就行,避免重复加载:

import importlib.util
import inspect
import sys
from test import Test

t = Test()

module_name = 'test'
# 先检查缓存里有没有目标模块,有就直接用
if module_name in sys.modules:
    module = sys.modules[module_name]
else:
    spec = importlib.util.spec_from_file_location(module_name, './test.py')
    module = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(module)
    # 加载完存入缓存,避免后续重复加载
    sys.modules[module_name] = module

# 直接通过模块属性获取类,比遍历更精准
loaded_test = module.Test

print(isinstance(t, loaded_test))  # 现在会返回True

2. 重新加载模块(适用于文件内容更新的场景)

如果你是因为test.py内容有修改,需要刷新模块,那可以用importlib.reload刷新已有的模块:

import importlib
import sys
from test import Test

t = Test()

# 重新加载已有的test模块
module = importlib.reload(sys.modules['test'])
loaded_test = module.Test

# 注意:旧实例t还是属于原来的Test类,如果模块里的Test有修改,isinstance会返回False
# 这种方式适合用新类创建新实例的场景
new_t = loaded_test()
print(isinstance(new_t, loaded_test))  # 返回True

3. 统一用动态加载的方式创建实例

如果你的场景就是要动态加载类,那干脆全程用动态加载的类来创建实例,别混合两种加载方式:

import importlib.util

spec = importlib.util.spec_from_file_location('test', './test.py')
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)

loaded_test = module.Test
t = loaded_test()  # 用动态加载的类创建实例

print(isinstance(t, loaded_test))  # 肯定返回True

内容的提问来源于stack exchange,提问作者Daniel Drexler

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:54:10