导入子类后Command.__subclasses__()返回空列表,原因是什么?
你遇到的是模块导入命名空间冲突导致的问题:当直接运行logic.py时,该模块的__name__会被设为__main__;而comm.py里通过from logic import Command导入的是名为logic的模块(即同一个文件,但以模块身份加载,而非主程序),这就产生了两个独立的Command类:
- 主程序中的
__main__.Command - 模块中的
logic.Command
你的TestCommand继承的是logic.Command,但调试时访问的Command是__main__.Command,所以它的__subclasses__()返回空列表。调试输出里的comm.TestCommand.__mro__显示<class 'logic.Command'>,正好验证了这一点。
有两种方式可以解决这个问题:
方式1:使用独立入口脚本
创建一个单独的入口文件(比如main.py),避免直接运行logic.py:
# main.py from logic import Commands if __name__ == "__main__": cmd_dict = Commands()
运行时执行python main.py,此时logic模块的__name__是logic,comm.py导入的Command和logic模块中的Command是同一个类,TestCommand会被正常添加到Command.__subclasses__()列表中。
方式2:修改logic.py的直接运行逻辑
如果需要直接运行logic.py,可以在文件末尾添加如下代码,确保导入的是正确的模块版本:
# logic.py末尾添加 if __name__ == "__main__": # 重新导入自身作为模块 import logic cmd_dict = logic.Commands()
这样当直接运行logic.py时,会加载logic模块(而非__main__),保证Command类的唯一性。
在调试时可以执行以下命令确认类的身份:
(Pdb) id(Command) # 主程序中__main__.Command的ID (Pdb) id(comm.TestCommand.__bases__[0]) # logic.Command的ID
这两个ID会不同,证明是两个独立的类;使用上述解决方案后,两个ID会一致,Command.__subclasses__()也会返回[<class 'comm.TestCommand'>]。
内容的提问来源于stack exchange,提问作者Gennadiy

