Python3如何获取其他包内所有类并实现实例化?
解决方案:自动导入Python包内所有文件的类
错误原因分析
- 你用
from system.models import *报错,是因为默认情况下,这个语句导入的是models包下的模块文件,而非模块里的类。所以globals()[class_name]拿到的是模块对象,无法调用实例化,才会抛出TypeError: 'module' object is not callable。 - 直接修改
sys.path只是把目标目录加入Python的搜索路径,但没有实际执行导入操作,因此globals()里不会出现目标类。
实现步骤(无需逐个导入,代码量不随类数变化)
核心思路是利用Python包的__init__.py文件,自动遍历并导入包内所有模块的类,统一暴露到包的命名空间中。
确保目标文件夹是Python包:如果
system/models目录下没有__init__.py,新建一个空文件即可。编写
__init__.py的自动导入逻辑:
将以下代码写入system/models/__init__.py,它会自动遍历所有.py文件,导入模块并提取其中的类:
import os import importlib import inspect from inspect import isclass # 获取当前包的目录路径 package_dir = os.path.dirname(__file__) # 遍历目录下所有Python文件(排除__init__.py本身) for filename in os.listdir(package_dir): if filename.endswith('.py') and filename != '__init__.py': # 提取模块名(去掉.py后缀) module_name = filename[:-3] # 相对导入当前包下的模块 module = importlib.import_module(f'.{module_name}', package=__name__) # 遍历模块成员,筛选出类并添加到包的命名空间 for name, obj in inspect.getmembers(module, isclass): # 将类注册到当前包的全局命名空间 globals()[name] = obj
- 主代码中使用类:
现在你可以直接从包中导入所有类,或者通过包的命名空间获取类:
# 方式1:导入所有类到当前命名空间 from system.models import * model = globals()[class_name](labels.size()[:-1], labels.size()[-1]) # 方式2:直接通过包获取(更安全,避免全局命名空间冲突) import system.models model = getattr(system.models, class_name)(labels.size()[:-1], labels.size()[-1])
注意事项
- 如果不同模块中有同名类,后导入的类会覆盖先导入的,建议确保类名唯一。
- 确保所有
.py文件都是合法的Python模块(无语法错误),否则会导致导入失败。
内容的提问来源于stack exchange,提问作者John Glen
相关产品推荐
相关产品推荐

