[英]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.