Pythonアプリケーションの配布クロスプラットフォーム
-
18-09-2019 - |
質問
私は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
私の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"]),
]
)
次に、b.pyに(これはOSX上で):
from app.mod2.b import *
私が入手ます:
ImportError: No module named mod2.b
だから、基本的に、MOD2はMOD1をacccessすることはできません。 Pythonモジュール「アプリ」がは/ usr /共有/ pysharedでグローバルにインストールされているため、Linuxでは、全く問題ありません。しかし、OSX上のアプリは明らかにpy2appによって構築された自己完結型の.app事になります。私は、これは完全に間違って近づいた場合OSX上のPythonアプリケーションを配布する際に、任意のベストプラクティスがあるだろうか?
編集:私もb.pyにこのようなハックを試します:
from ..mod2.b import *
ValueError: Attempted relative import beyond toplevel package
EDIT2:この ?の
解決
私は(私は適切な分布にかなりの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)
私は、クロスプラットフォームな方法で正しいことを行うべきだと思います。
EDIT:kaizer.seが指摘するように、これはあなたが呼び出しているコードが実行取得方法に応じて、__init__.py
ファイルでは動作しない可能性があります。そのファイルが評価されている場合にのみ動作します。キーはトップレベルのパッケージが実際に実行されているいくつかのコードからsys.path
であることを確認することです。
多くの時間を、私は(if __name__ eq '__main__'
イディオムとテストのために)直接、パッケージ内の個々のファイルを実行するように、私は場所のような何か文をやります
import _setup
問題の個々のファイルの先頭に、その後、パスは、必要に応じていじるんファイル_setup.py
を作成します。だから、何かます:
package/
__init__.py
_setup.py
mod1/
__init__.py
_setup.py
somemodule.py
あなたはimport _setup
からsomemodule.py
場合は、、その設定ファイルがsys.path
内のコードの残りの部分が評価される前に、トップ・レベル・パッケージがsomemodule.py
にあることを確認することができます。