有两个带有命令链的文件和一个动态收集所有非抽象命令的字典。
from abc import ABC, abstractmethod
class Command(ABC):
def __init__(self):
...
@abstractmethod
def run():
...
class Commands(dict):
def __init__(self):
import comm
breakpoint()
for cls in Command.__subclasses__():
names = self.split_camel_case(cls.__name__)
self[names] = cls
from logic import Command
class TestCommand(Command):
...
> logic.py(28) __init__()
-> for cls in Command.__subclasses__():
(Pdb) comm.TestCommand.__mro__
(<class 'comm.TestCommand'>, <class 'logic.Command'>, <class 'abc.ABC'>, <class 'object'>)
(Pdb) Command.__subclasses__()
[]
当
Commands.__init__()
被称为基类 Command
时,已经定义了。模块 comm
被导入,子类 TestCommand
也被定义。但是Command.__subclass__()
返回的列表是空的。
请告诉我,我错过了什么?
我认为问题在于,令人困惑的是,您从
Command
内部看到的 Commands.__init__
类对象与 TestCommand
继承自的对象不同。
在某种程度上,是的,它们是相同的,但对于 Python 导入系统来说,它们是不同的。
尝试这段代码,看看会发生什么:
logic.py
from abc import ABC, abstractmethod
class Command(ABC):
def __init__(self):
...
@abstractmethod
def run():
...
class Commands(dict):
def __init__(self):
import comm
print(Command.__module__)
print(Command.__subclasses__())
if __name__ == "__main__":
Commands()
comm.py
from logic import Command
class TestCommand(Command):
...
if __name__ == "__main__":
print(Command.__module__)
print(Command.__subclasses__())
$ python comm.py
logic
[<class '__main__.TestCommand'>]
$ python logic.py
__main__
[]
请注意两个
Command
类引用如何具有不同的 __module__
值。
Commands.__init__
具有对其所属模块完全定义之前定义的 Command
类的引用。
我们可以通过将逻辑移至第三个文件来解决此问题:
base.py
from abc import ABC, abstractmethod
class Command(ABC):
def __init__(self):
...
@abstractmethod
def run():
...
comm.py
from base import Command
class TestCommand(Command):
...
logic.py
from base import Command
import comm
class Commands(dict):
def __init__(self):
print(Command.__module__)
print(Command.__subclasses__())
if __name__ == "__main__":
Commands()
现在,当我们运行它时,我们得到了想要的结果:
$ python logic.py
base
[<class 'comm.TestCommand'>]