Python py2app:如何包含将由导入加载的模块?

Python py2app:如何包含将由导入加载的模块?,python,macos,py2app,Python,Macos,Py2app,我有一个Python应用程序,它在运行时动态加载Python模块(使用\uuuuu import\uuuu)。要加载的模块位于名为“plugins”的包中(即名为plugins的子文件夹,其中包含\uuu init\uuuuuuy.py等)。在python解释器中运行,甚至在使用py2exe编译为windows二进制文件时,所有这些都可以正常工作 我尝试用它构建OSX应用程序,但成功了,但在运行.app时,我得到一个ImportError:“没有名为plugins.xxxx的模块。” 我非常确定

我有一个Python应用程序,它在运行时动态加载Python模块(使用
\uuuuu import\uuuu
)。要加载的模块位于名为“
plugins
”的包中(即名为
plugins
的子文件夹,其中包含
\uuu init\uuuuuuy.py
等)。在python解释器中运行,甚至在使用py2exe编译为windows二进制文件时,所有这些都可以正常工作

我尝试用它构建OSX应用程序,但成功了,但在运行.app时,我得到一个ImportError:“
没有名为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
文件夹。现在找到了插件。但是我仍然不满意这种丑陋的手工破解。您可能需要执行类似的操作来检测您是否在py2app中,并相应地调整导入


Koo使用以下代码。您可能需要执行类似的操作来检测您是否在py2app中,并相应地调整导入

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] )