Python中的__subclasses__()未列出子类

7 投票
2 回答
5574 浏览
提问于 2025-04-16 00:01

我似乎无法通过 __subclasses__() 方法列出所有的派生类。我的目录结构是这样的:

import.py
backends
      __init__.py
    --digger
          __init__.py
          base.py
          test.py
        --plugins
              plugina_plugin.py

我从 import.py 文件中调用 test.py。然后 test.py 会遍历 plugins 目录中的所有文件,并加载它们。 test.py 的内容如下:

import os
import sys
import re

sys.path.append(os.path.join(os.path.abspath(os.path.dirname(os.path.abspath( __file__ )))))
sys.path.append(os.path.join(os.path.abspath(os.path.dirname(os.path.abspath( __file__ ))), 'plugins'))

from base import BasePlugin

class TestImport:
    def __init__(self):
        print 'heeeeello'

        PLUGIN_DIRECTORY = os.path.join(os.path.abspath(os.path.dirname(os.path.abspath( __file__ ))), 'plugins')

        for filename in os.listdir (PLUGIN_DIRECTORY):
            # Ignore subfolders
            if os.path.isdir (os.path.join(PLUGIN_DIRECTORY, filename)):
                continue
            else:
                if re.match(r".*?_plugin\.py$", filename):
                    print ('Initialising plugin : ' + filename)
                    __import__(re.sub(r".py", r"", filename))

        print ('Plugin system initialized')
        print BasePlugin.__subclasses__()

问题是 __subclasses__() 方法没有显示任何派生类。plugins 目录中的所有插件都是从 base.py 文件中的一个基类派生出来的。

base.py 的内容如下:

class BasePlugin(object):
    """
    Base
    """
    def __init__(self):
        pass

plugina_plugin.py 的内容如下:

from base import BasePlugin

class PluginA(BasePlugin):
    """
    Plugin A
    """
    def __init__(self):
        pass

有没有人能帮我解决这个问题?我到底哪里做错了?我想了很多,但就是搞不明白。

谢谢。

2 个回答

0

也许这些插件在其他地方找到了另一个 base.py 文件(比如在插件目录里)。
你可以用 python -v 命令来查看是否有两个不同的 base.py 文件被导入了。

你还可以查看 PluginA.__mro__,确认里面的 BasePlugin 是正确的那个。

7

我没有其他的base.py文件。我在使用Windows XP(SP2)和Python 2.6。我在我的test.py文件里添加了一个叫PluginB的新类,它使用BasePlugin作为基类。当我执行了以下代码:

    print PluginA.__mro__
    print PluginB.__mro__

我得到了:

(<class 'plugina_plugin.PluginA'>, <class 'base.BasePlugin'>, <type 'object'>)
(<class 'backends.digger.test.PluginB'>, <class 'backends.digger.base.BasePlugin'>, <type 'object'>)

正如你所看到的,它们都在使用同一个基插件,但它们的名称却不同。这是因为在plugina_plugin.py文件中,我是这样导入BasePlugin的:

from base import BasePlugin

而不是这样:

from backends.digger.base import BasePlugin

修正这个问题后,一切就正常了。

撰写回答