質問

私は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にあることを確認することができます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top