【问题标题】:py2app: how to include modules that will be loaded by __import__?py2app:如何包含将由 __import__ 加载的模块?
【发布时间】:2010-08-19 20:31:10
【问题描述】:

我有一个 Python 应用程序,它在运行时动态加载 Python 模块(使用 __import__)。要加载的模块位于名为“plugins”的包中(即名为plugins__init__.py 等的子文件夹)。从 python 解释器运行一切正常,即使使用 py2exe 编译为 Windows 二进制文件。

我尝试从中构建一个 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文件夹下。现在插件找到了。但我仍然对这种丑陋的手动 hack 不满意。

【问题讨论】:

    标签: python macos py2app


    【解决方案1】:

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

    【讨论】:

      猜你喜欢
      • 2012-06-07
      • 1970-01-01
      • 1970-01-01
      • 2013-11-09
      • 1970-01-01
      • 1970-01-01
      • 2017-07-20
      • 1970-01-01
      • 2011-05-29
      相关资源
      最近更新 更多