2009-11-06 227 views
2

我想分發我的應用程序在OSX(使用py2app)和Debian軟件包。Python應用程序分發跨平臺

我的應用程序的結構是這樣的:

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。在Linux上沒有問題,因爲python模塊'app'全局安裝在/ usr/shared/pyshared中。但是在OSX上,應用程序顯然是一個由py2app構建的獨立的.app應用程序。我想知道我是否完全錯誤,在OSX上發佈Python應用程序時是否有最佳做法?

編輯:我也試過這樣的黑客在b.py:

from ..mod2.b import * 

ValueError: Attempted relative import beyond toplevel package 

EDIT2:似乎與此有關How to do relative imports in Python?

回答

5

我不知道這是否是「最佳實踐'或者沒有(我沒有把很多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) 

我覺得應該做正確的事在跨平臺的方式。

編輯:正如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 _setupsomemodule.py,該安裝文件可以確保頂層包在sys.path代碼的somemodule.py其餘的評估之前。

+0

這可以解決嗎?如果應用程序不在路徑中,應用程序如何首先到達程序包的__init__模塊? – u0b34a0f6ae