如何以编程方式查找使用 Python import * 命令导入的符号?

tin*_*tic 3 python import python-import

我有一个系统,它收集从某些基类派生的所有类并将它们存储在字典中。我想避免必须指定哪些类可用(我想以编程方式发现它们),因此使用了一个from ModuleName import *语句。然后引导用户将要收集的所有测试放入模块中ModuleName。但是,我找不到一种方法来以编程方式确定使用该导入语句导入了哪些符号。我已尝试使用dir()和 ,__dict__如以下示例所示,但无济于事。如何以编程方式查找以这种方式导入的符号(使用import *)?我用上面的方法都找不到他们。

测试类型图Outerrer.py:

from testType1 import *
from testType2 import *

class TestFigureOuterrer(object):

    def __init__(self):
        self.existingTests = {'type1':{},'type2':{}}

    def findAndSortTests(self):

        for symbol in dir(): # Also tried: dir(self) and __dict__
            try:
                thing = self.__getattribute__(symbol)
            except AttributeError:
                continue
            if issubclass(thing,TestType1):
                self.existingTests['type1'].update( dict(symbol,thing) )
            elif issubclass(thing,TestType3):
                self.existingTests['type2'].update( dict(symbol,thing) )
            else:
                continue

if __name__ == "__main__":
    testFigureOuterrer = TestFigureOuterrer()
    testFigureOuterrer.findAndSortTests()
Run Code Online (Sandbox Code Playgroud)

测试类型1.py:

class TestType1(object):
    pass

class TestA(TestType1):
    pass

class TestB(TestType1):
    pass
Run Code Online (Sandbox Code Playgroud)

测试类型2.py:

class TestType2:
    pass

class TestC(TestType2):
    pass

class TestD(TestType2):
    pass
Run Code Online (Sandbox Code Playgroud)

pok*_*oke 5

由于您自己知道导入,因此您应该再次手动导入模块,然后检查模块的内容。如果__all__定义了属性,则在您执行此操作时,其内容将作为名称导入from module import *。否则,只需使用其所有成员:

\n\n
def getImportedNames (module):\n    names = module.__all__ if hasattr(module, '__all__') else dir(module)\n    return [name for name in names if not name.startswith('_')]\n
Run Code Online (Sandbox Code Playgroud)\n\n

这样做的好处是您不需要遍历全局变量并过滤掉所有内容。由于您知道在设计时导入的模块,因此您还可以直接检查它们。

\n\n
from testType1 import *\nfrom testType2 import *\n\nimport testType1, testType2\n\nprint(getImportedNames(testType1))\nprint(getImportedNames(testType2))\n
Run Code Online (Sandbox Code Playgroud)\n\n

或者,您也可以通过模块名称从 查找模块sys.modules,因此您实际上不需要额外的导入:

\n\n
import sys\ndef getImportedNames (moduleName):\n    module = sys.modules[moduleName]\n    names = module.__all__ if hasattr(module, '__all__') else dir(module)\n    return [name for name in names if not name.startswith('_')]\n
Run Code Online (Sandbox Code Playgroud)\n\n\n\n
print(getImportedNames('testType1'))\nprint(getImportedNames('testType2'))\n
Run Code Online (Sandbox Code Playgroud)\n