2010-08-19 47 views
2

我有一個Python應用程序,在運行時動態加載python模塊(使用__import__)。要加載的模塊位於名爲'plugins'的包中(即子文件夾名爲plugins__init__.py等)。從python解釋器運行良好,甚至在使用py2exe編譯爲windows二進制文件時也是如此。py2app:如何包含將由__import__加載的模塊?

我試着從它建立一個OSX應用程序,它成功了,但是當運行.app時,我得到一個ImportError:'no module named plugins.xxxx'。

我敢肯定我給了正確的選擇,py2app('includes': [...]'packages':['plugins'],等同於我的py2exe做),因爲當我瀏覽的.app內容,我看到一個文件夾Contents/Resources/lib/python2.5/plugins/中的所有插件模塊。

那麼,爲什麼不能找到我的模塊(必須是一些路徑問題)?

編輯:

我已經找到一種方法,使其工作,但它不是一個很好的解決方案: 當我打印路徑的Python搜索模塊(使用print sys.path),我注意到,文件夾Contents/Resources/lib/python2.5/plugins/未列出。但是,文件夾Contents/Resources/是,所以我將plugins文件夾移動到Contents/Resources文件夾。現在找到了插件。但我對這個醜陋的手工破解仍然不滿意。

回答

0

Koo使用以下代碼。你可能需要做類似的事情來檢測你是否在py2app中,並相應地調整你的導入。

http://bazaar.launchpad.net/~openobject-client-kde/openobject-client-kde/5.0/annotate/head%3A/Koo/Common/Plugins.py

def scan(module, directory): 
     pluginImports = __import__(module, globals(), locals()) 
     # Check if it's being run using py2exe or py2app environment 
     frozen = getattr(sys, 'frozen', None) 
     if frozen == 'macosx_app' or hasattr(pluginImports, '__loader__'): 
       # If it's run using py2exe or py2app environment, all files will be in a single 
       # zip file and we can't use listdir() to find all available plugins. 
       zipFiles = pluginImports.__loader__._files 
       moduleDir = os.sep.join(module.split('.')) 
       files = [zipFiles[file][0] for file in zipFiles.keys() if moduleDir in file] 
       files = [file for file in files if '__init__.py' in file] 
       for file in files: 
         d = os.path.dirname(file) 
         if d.endswith(moduleDir): 
           continue 
         newModule = os.path.basename(os.path.dirname(file)) 
         __import__('%s.%s' % (module, newModule), globals(), locals(), [newModule]) 
     else: 
       for i in os.listdir(directory): 
         path = os.path.join(directory, i, '__init__.py') 
         if os.path.isfile(path): 
           __import__('%s.%s' % (module, i), globals(), locals(), [i])