Python应用程序跨平台分发

Python应用程序跨平台分发,python,cross-platform,setuptools,py2app,Python,Cross Platform,Setuptools,Py2app,我想使用py2app和Debian软件包在OSX上发布我的应用程序 我的应用程序的结构如下所示: app/ debian/ <lots of debian related stuff> scripts/ app app/ __init__.py app.py mod1/ __init__.py a

我想使用py2app和Debian软件包在OSX上发布我的应用程序

我的应用程序的结构如下所示:

app/
     debian/
            <lots of debian related stuff>
     scripts/
             app
     app/
         __init__.py
         app.py
         mod1/
              __init__.py
              a.py
         mod2/
              __init__.py
              b.py
然后,在b.py中,这是在OSX上:

from app.mod2.b import *
我得到:

ImportError: No module named mod2.b
所以基本上,mod2无法访问mod1。在Linux上没有问题,因为python模块“app”全局安装在/usr/shared/pyshared中。但在OSX上,应用程序显然是由py2app构建的一个独立的应用程序。我想知道我的做法是否完全错误,在OSX上发布Python应用程序时有什么最佳实践吗

编辑:我在b.py中也尝试过这样的破解:

from ..mod2.b import *

ValueError: Attempted relative import beyond toplevel package

Edit2:似乎与此相关

我不确定这是否是“最佳实践”,我没有将太多python软件放入适当的发行版中,但我只想确保顶级应用程序包位于sys.path中。类似于将以下内容放入顶级的_init__uu.py中:

我认为这应该以跨平台的方式做正确的事情

编辑:正如kaizer.se指出的那样,这可能在_init__u;.py文件中不起作用,这取决于您调用的代码的执行方式。它只有在对该文件求值时才起作用。关键是确保顶级包位于实际运行的代码的sys.path中

通常情况下,为了使用if\uuuu name\uuuuueq'\uuuuu main\uuuuu'习惯用法直接执行包中的单个文件进行测试,我会执行一些类似于放置语句的操作:

import _setup
然后创建一个文件_setup.py,根据需要执行路径搜索。比如说:

from setuptools import setup
import os
import os.path

osname = os.uname()[0]

if osname == 'Darwin':
    APP = ['app/app.py']
    DATA_FILES = []
    OPTIONS = {'argv_emulation': True}

    setup(
        app=APP,
        data_files=DATA_FILES,
        options={'py2app': OPTIONS},
        setup_requires=['py2app'],
    )
elif osname == 'Linux':
        setup(
        name = "app",
        version = "0.0.1",
        description = "foo bar",
        packages = ["app", "app.mod1", "app.mod2"],
        scripts = ["scripts/app"],
        data_files = [
            ("/usr/bin", ["scripts/app"]),
       ]
    )
package/
    __init__.py
    _setup.py
    mod1/
        __init__.py
        _setup.py
        somemodule.py

如果从somemodule.py导入_安装程序,该安装文件可以确保在计算somemodule.py中的其余代码之前,顶层包位于sys.path中。

这是解决方案吗?如果应用程序不在路径中,它首先将如何到达包的init模块?
package/
    __init__.py
    _setup.py
    mod1/
        __init__.py
        _setup.py
        somemodule.py