簡體   English   中英

如何以編程方式查找使用Python import *命令導入的符號?

[英]How do I programatically find what symbols were imported with Python import * command?

我有一個系統,它收集從某些基類派生的所有類,並將它們存儲在字典中。 我想避免必須指定哪些類可用(我想以編程方式發現它們),所以使用了一個from ModuleName import *語句。 然后指示用戶將要收集的所有測試放在ModuleName模塊中。 但是,我找不到以編程方式確定使用該import語句導入了哪些符號的方法。 我已嘗試使用dir()__dict__如以下示例所示,但無濟於事。 如何以編程方式查找以這種方式import *符號(使用import * )? 我無法用上述方法找到它們。

testTypeFigureOuterrer.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()

testType1.py:

class TestType1(object):
    pass

class TestA(TestType1):
    pass

class TestB(TestType1):
    pass

testType2.py:

class TestType2:
    pass

class TestC(TestType2):
    pass

class TestD(TestType2):
    pass

由於您自己了解導入,因此您應該再次手動導入模塊,然后檢查模塊的內容。 如果定義了__all__屬性,則在from module import *執行時將其內容作為名稱from module import * 否則,只需使用其所有成員:

def getImportedNames (module):
    names = module.__all__ if hasattr(module, '__all__') else dir(module)
    return [name for name in names if not name.startswith('_')]

這樣做的好處是您不需要遍歷全局變量,並將所有內容過濾掉。 既然你知道在設計時導入的模塊,你也可以直接檢查它們。

from testType1 import *
from testType2 import *

import testType1, testType2

print(getImportedNames(testType1))
print(getImportedNames(testType2))

或者,您也可以通過sys.modules模塊名稱查找模塊,因此您實際上不需要額外的導入:

import sys
def getImportedNames (moduleName):
    module = sys.modules[moduleName]
    names = module.__all__ if hasattr(module, '__all__') else dir(module)
    return [name for name in names if not name.startswith('_')]
print(getImportedNames('testType1'))
print(getImportedNames('testType2'))

看一下這個SO答案 ,它描述了如何確定已加載類的名稱,您可以獲得在模塊上下文中定義的所有類的名稱。

import sys, inspect
clsmembers = inspect.getmembers(sys.modules['testType1'], inspect.isclass)

現在定義為

[('TestA', testType1.TestA),
 ('TestB', testType1.TestB),
 ('TestType1', testType1.TestType1)]

您也可以替換testType1__name__當你感興趣的函數中。

不要使用*形式的import 這會將導入的名稱轉儲到腳本的全局名稱空間中。 它們不僅可以通過使用相同的名稱來破壞一些重要的數據,而且您沒有任何簡單的方法來刪除剛剛導入的名稱。 (最簡單的方法可能是在之前和之后拍攝globals().keys()的快照。)

相反,只導入模塊:

import testType1
import testType2

現在,您可以輕松獲取每個模塊中的內容列表:

tests = dir(testType1)

並使用模塊對象上的getattr()訪問每個:

for testname in tests:
    test = getattr(testType1, testname)
    if callable(test):
        # do something with it

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM