poj*_*ojo 2 python cross-platform setuptools py2app
我想在OSX(使用py2app)和Debian软件包上分发我的应用程序.
我的应用程序的结构如下:
app/
debian/
<lots of debian related stuff>
scripts/
app
app/
__init__.py
app.py
mod1/
__init__.py
a.py
mod2/
__init__.py
b.py
Run Code Online (Sandbox Code Playgroud)
我的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"]),
]
)
Run Code Online (Sandbox Code Playgroud)
然后,在b.py(这是在OSX上):
from app.mod2.b import *
Run Code Online (Sandbox Code Playgroud)
我明白了:
ImportError: No module named mod2.b
Run Code Online (Sandbox Code Playgroud)
所以基本上,mod2不能接受mod1.在Linux上没有问题,因为python模块'app'全局安装在/ usr/shared/pyshared中.但是在OSX上,应用程序显然是一个由py2app构建的自包含.app的东西.我想知道我是否接近这个完全错误,在OSX上分发Python应用程序时是否有最佳实践?
编辑:我也在b.py中试过这样的hack:
from ..mod2.b import *
ValueError: Attempted relative import beyond toplevel package
Run Code Online (Sandbox Code Playgroud)
Edit2:似乎与此相关如何在Python中进行相对导入?
我不确定这是否是"最佳实践"(我没有把很多python软件放到正确的发行版中),但我只是确保顶级应用程序包在sys.path.有点像将以下内容放入顶层__init__.py:
try:
import myapp
except ImportError:
import sys
from os.path import abspath, dirname, split
parent_dir = split(dirname(abspath(__file__)))[0]
sys.path.append(parent_dir)
Run Code Online (Sandbox Code Playgroud)
我认为应该以跨平台的方式做正确的事情.
编辑:正如kaizer.se所指出的,这可能在__init__.py文件中不起作用,具体取决于您调用的代码是如何执行的.只有在评估该文件时它才有效.关键是要确保顶层包sys.path来自实际运行的一些代码.
通常情况下,我直接在包内执行单个文件(用于使用if __name__ eq '__main__'成语进行测试),我会做一些像放置语句的事情:
import _setup
Run Code Online (Sandbox Code Playgroud)
在相关单个文件的顶部,然后创建一个文件_setup.py,根据需要执行路径修改.所以,像:
package/
__init__.py
_setup.py
mod1/
__init__.py
_setup.py
somemodule.py
Run Code Online (Sandbox Code Playgroud)
如果你import _setup来自somemodule.py,那个安装文件可以确保sys.path在somemodule.py评估其余代码之前顶层包.