2

実行時にPythonモジュールを動的にロードするPythonアプリケーションがあります(を使用__import__)。ロードするモジュールは、' plugins' というパッケージ (つまりplugins__init__.pyetc で呼び出されるサブフォルダ) にあります。python インタープリターから実行したり、py2exe を使用して Windows バイナリにコンパイルした場合でも、すべて正常に動作します。

そこから OSX アプリをビルドしようとしましたが、成功しましたが、.app を実行すると ImportError: ' no module named plugins.xxxx' が発生しました。

.app コンテンツを参照すると、フォルダー内のすべてのプラグイン モジュールが表示されるため、py2app (、、py2exe に対して行うことと同じ) に正しいオプションを指定したと確信'includes': [...]しています。'packages':['plugins']Contents/Resources/lib/python2.5/plugins/

では、なぜアプリがモジュールを見つけられないのでしょうか (何らかのパスの問題である必要があります)。

編集:

私はそれを機能させる方法を見つけましたが、それは良い解決策ではありません: Python が (を使用して) モジュールを検索するパスを印刷したとき、フォルダーがリストされていないprint sys.pathことに気付きました。Contents/Resources/lib/python2.5/plugins/ただ、フォルダContents/Resources/はあるので、pluginsフォルダをフォルダに移動しましたContents/Resources。これでプラグインが見つかりました。しかし、私はまだこの醜い手作業のハッキングに満足していません.

4

1 に答える 1

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] )
于 2011-01-07T17:11:56.863 に答える