2009-05-26 50 views
12

雖然在Python中導入一個「子」模塊到另一個模塊並列出其屬性相當簡單,但是當您想要導入所有子模塊時,它會變得稍微困難​​一些。如何在Python中查找所有子模塊?

我正在爲現有的3D應用程序構建工具庫。每個工具都有自己的菜單項和子菜單。我希望該工具負責創建自己的菜單,因爲其中許多菜單都是基於上下文和模板進行更改的。我希望我的基本模塊能夠找到所有子模塊並檢查create_menu()函數,並在找到它時調用它。

發現所有子模塊的最簡單方法是什麼?

+0

這與此相關嗎? [(setuptools包中的'pkg_resources`]](http://jeetworks.org/node/49) – 2011-09-01 07:47:25

+1

使用[pkgutil.walk_packages](http://docs.python.org/library/pkgutil.html#pkgutil。 walk_packages)。 – Dag 2011-09-06 19:44:13

+1

模塊不是軟件包 – 2013-02-01 00:54:46

回答

1

當我在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] 

它不安全或「正確」的方式,但也許我們會很有用。這是非常舊代碼,所以請不要打我。

-1

您可以嘗試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) 
1

只要將每個插件實現爲基於文件系統的模塊,上述遍歷文件系統以找到子模塊的解決方案都可以。

一個更靈活的方法是在你的主模塊中一個顯式的插件列表,並且每個插件(無論是由文件,動態創建的模塊,還是一個類的實例)都明確地添加到列表中。也許通過registerPlugin函數。

請記住:「明確比隱含更好」是Python的禪宗的一部分。

相關問題