雖然在Python中導入一個「子」模塊到另一個模塊並列出其屬性相當簡單,但是當您想要導入所有子模塊時,它會變得稍微困難一些。如何在Python中查找所有子模塊?
我正在爲現有的3D應用程序構建工具庫。每個工具都有自己的菜單項和子菜單。我希望該工具負責創建自己的菜單,因爲其中許多菜單都是基於上下文和模板進行更改的。我希望我的基本模塊能夠找到所有子模塊並檢查create_menu()
函數,並在找到它時調用它。
發現所有子模塊的最簡單方法是什麼?
雖然在Python中導入一個「子」模塊到另一個模塊並列出其屬性相當簡單,但是當您想要導入所有子模塊時,它會變得稍微困難一些。如何在Python中查找所有子模塊?
我正在爲現有的3D應用程序構建工具庫。每個工具都有自己的菜單項和子菜單。我希望該工具負責創建自己的菜單,因爲其中許多菜單都是基於上下文和模板進行更改的。我希望我的基本模塊能夠找到所有子模塊並檢查create_menu()
函數,並在找到它時調用它。
發現所有子模塊的最簡單方法是什麼?
當我在Python是一種和剛剛開始編程,我寫這個我模塊化IRC殭屍:
# Load plugins
_plugins = []
def ifName(name):
try:
return re.match('([^_.].+)\.[^.]+', a).group(1)
except:
return None
def isValidPlugin(obj):
from common.base import PluginBase
try:
if obj.__base__ == PluginBase:
return True
else:
return False
except:
return False
plugin_names = set(ifilter(lambda a: a!=None, [ifName(a) for a in os.listdir(os.path.join(os.getcwd(), 'plugins'))]))
for plugin_name in plugin_names:
try:
plugin = __import__('plugins.'+plugin_name, fromlist=['plugins'])
valid_plugins = filter(lambda a: isValidPlugin(a), [plugin.__getattribute__(a) for a in dir(plugin)])
_plugins.extend(valid_plugins)
except Exception, e:
logger.exception('Error loading plugin %s', plugin_name)
# Run plugins
_plugins = [klass() for klass in _plugins]
它不安全或「正確」的方式,但也許我們會很有用。這是非常舊代碼,所以請不要打我。
您可以嘗試glob
兵的目錄:
import os
import glob
modules = glob.glob(os.path.join('/some/path/to/modules', '*.py'))
這時可以嘗試導入它們:
checked_modules
for module in modules:
try:
__import__(module, globals(), locals()) # returns module object
except ImportError:
pass
else:
checked_modules.append(module)
我覺得做這樣的插件事情的最好方法是使用entry_points
和API for querying them。
只要將每個插件實現爲基於文件系統的模塊,上述遍歷文件系統以找到子模塊的解決方案都可以。
一個更靈活的方法是在你的主模塊中一個顯式的插件列表,並且每個插件(無論是由文件,動態創建的模塊,還是一個類的實例)都明確地添加到列表中。也許通過registerPlugin函數。
請記住:「明確比隱含更好」是Python的禪宗的一部分。
這與此相關嗎? [(setuptools包中的'pkg_resources`]](http://jeetworks.org/node/49) – 2011-09-01 07:47:25
使用[pkgutil.walk_packages](http://docs.python.org/library/pkgutil.html#pkgutil。 walk_packages)。 – Dag 2011-09-06 19:44:13
模塊不是軟件包 – 2013-02-01 00:54:46