Python中如何使用变量指定类名从模块中导入对应特定类?
问题编辑说明
此问题最初基于我可仅导入模块部分内容无需导入整个模块的假设,实际该假设不成立,因此我最终采用
from ex45_extras import *导入整个模块。我未删除此问题,希望其他有相同疑问的初学者能了解:Python无法拆分导入模块的部分内容
原始问题
我是Python初学者,想要通过变量指定类名从模块中导入对应特定类,不想导入整个模块,且需要通过Nav类控制导入的类,请问是否有实现方法,或是更优的解决方案?
问题代码
class Nav(): def __init__(self): print("This is class Nav") def play(self): current_scene_name = "A()" # 此处定义存储类名的变量 from ex45_extras import current_scene_name # 此行是问题相关导入代码 x = Nav() x.play()
报错信息
This is class Nav Traceback (most recent call last): File "D:\\Programming\\Python\\LPTHW_Exs\\ex45\\test.py", line 11, in <module> x.play() File "D:\\Programming\\Python\\LPTHW_Exs\\ex45\\test.py", line 7, in play from ex45_extras import current_scene_name ImportError: cannot import name 'current_scene_name' from 'ex45_extras' (D:\\Programming\\Python\\LPTHW_Exs\\ex45\\ex45_extras.py)
解决方案
报错原因
from ... import 后直接跟的标识符是字面量,Python不会将它识别为你之前定义的变量,因此会直接去ex45_extras模块中查找名为current_scene_name的属性,自然会报错。同时你定义的current_scene_name多写了(),这是实例化类的写法,单独的类名只需要写"A"即可。
按需动态导入指定类的实现方法
可以用Python标准库的importlib模块实现按变量名导入指定对象,不需要导入整个模块的所有内容到当前命名空间:
import importlib class Nav(): def __init__(self): print("This is class Nav") def play(self): current_scene_name = "A" # 仅存储类名字符串 # 导入目标模块 target_module = importlib.import_module("ex45_extras") # 从模块中提取对应类 scene_class = getattr(target_module, current_scene_name) # 实例化类即可使用 current_scene = scene_class() x = Nav() x.play()
补充说明
Python导入模块时本质会加载整个模块到内存,不存在“只导入部分内容就不加载全模块”的情况,from module import xxx和import module的区别仅在于把哪些名称引入当前命名空间,而非加载的模块内容多少。上述动态导入的写法不会引入多余名称污染当前命名空间,比import *更安全规范。
内容的提问来源于stack exchange,提问作者Necryl
相关产品推荐
相关产品推荐

