如何使用__import__导入类而非模块?代码仅导入模块的问题
解决动态导入Module1/Module2类的问题
你的问题出在__import__函数的行为上——当你导入像module1.module1这样的嵌套模块时,__import__默认返回的是顶层模块(也就是module1),而不是你指定的子模块module1.module1。这就导致你后续用getattr拿到的是子模块对象,而不是里面的Module1类。
下面给你几种可行的解决方案:
方案1:使用importlib.import_module(推荐)
Python 2.7+和3.x都支持的importlib模块提供了更直观的import_module函数,它会直接返回你指定的模块对象,用起来更不容易出错:
import importlib module_list = ['module1.module1', 'module2.module2'] for module_path in module_list: if some_condition: # 导入指定的子模块 mod = importlib.import_module(module_path) # 获取模块里的类(比如Module1或Module2) class_name = module_path.split(".")[-1].capitalize() # 转换为首字母大写的类名 class_ = getattr(mod, class_name) setattr(self, 'target_attr_name', class_) # 替换为你要设置的属性名字符串
方案2:修正__import__的用法
如果你坚持要用__import__,需要给它加上fromlist参数,这样它会返回你指定的子模块:
module_list=['module1.module1', 'module2.module2'] for module in module_list: if some_condition: # 加上fromlist=[''],让__import__返回子模块而非顶层模块 mod = __import__(module, fromlist=['']) class_name = module.split(".")[1].capitalize() class_ = getattr(mod, class_name) setattr(self, 'target_attr_name', class_)
方案3:利用你已有的__init__.py简化导入
因为你的每个模块的__init__.py已经把类导入到了顶层模块(比如module1模块下直接有Module1类),所以你其实可以直接导入顶层模块,然后直接取类:
module_list=['module1', 'module2'] for module_name in module_list: if some_condition: mod = __import__(module_name) class_ = getattr(mod, module_name.capitalize()) # 直接从顶层模块取已导入的类 setattr(self, 'target_attr_name', class_)
另外注意:你的代码里setattr(self, m1, class_)中的m1应该是一个字符串类型的属性名,比如如果要把类赋值给self.module1,那应该写成setattr(self, 'module1', class_),不然会触发变量未定义的错误哦。
内容的提问来源于stack exchange,提问作者kostas
相关产品推荐
相关产品推荐

