2012-11-17 29 views
2

我正在使用Python編寫的包裝器腳本。包裝應該根據系統狀態選擇另一個Python腳本並執行它(使用絕對路徑)。沒有必要返回到父腳本。使用不同的腳本有效地重新執行Python解釋器

應當指出的是,我在劇本正在運行的控制。他們可以使用__name__檢查,訪問sys.argv,它應該像腳本直接運行一樣。

現在,我使用os.execl()

import os, sys 

# ... 

os.execl(sys.executable, sys.executable, new_script, *sys.argv[1:]) 

但我可以指望至少有三個問題與:傳遞給Python解釋器

  1. 任何選項都不會保留(如python -v wrapper停止在re-exec上冗長);
  2. Python解釋器被不必要地重新執行(使用PyPy它會在我的系統上添加0.7s);
  3. 它依賴於sys.executable是有用的,和文檔說:

    如果Python是無法檢索到它的可執行文件真實路徑,sys.executable將是一個空字符串或None

我不知道我應該用什麼替代的 os.execl電話解決所有問題。到目前爲止,我可以告訴:

  1. execfile()可能會工作,但它是在Python3取出並用手AFAICS重新實現它是醜陋的(因爲編碼問題)。我不確定execfile()有什麼其他含義;
  2. imp.load_module()可能會工作,但它是一個有點哈克和Python3.3已被否決。它可能也會遭受Python3編碼問題。

哪種解決方案,你建議我用?


編輯:我會忘記。該解決方案必須使用Python 2.5+,PyPy和Jython 2.5+。

+2

你能'import'新的腳本? – martineau

+1

這看起來不錯,但你可以做一些驗證第一,Exec之前,也檢查sys.flags重建標誌。 – Keith

+0

我碰上其中'sys.executable'路徑包含空格,需要被引用到正常工作的情況。 – martineau

回答

1

我只想用execfile()代替imp.load_module()。雖然控制將返回到執行腳本,一個大優勢是,引用文檔:

距離import語句的不同之處在於它不使用 模塊管理 - 它讀取文件無條件不會 創建一個新的模塊。

這意味着該腳本文件可以在任何地方,可以有任何(或沒有)文件擴展名,資源不浪費做模塊導入相關的任務。

這樣做自動完成或避免你想要的東西:

  1. 解釋選項將被保留
  2. 解釋不會受到不必要的重新執行
  3. 它不依賴於sys.executable
-1

你有沒有試過類似的東西?

### wrapped script ### 

import sys 

print("__name__: {0}\nsys.argv: {1}".format(__name__, sys.argv)) 
### wrapper script ### 

import builtins, sys 

my_script = "wrapped_script.py" 

print("Executing the wrapped script...") 

sys.argv[0] = my_script 
with open(my_script, 'r') as fd: 
    for line in fd: 
     exec(line) 

結果:

$ python3 wrapped_script.py --foo --bar=quux 
__name__: __main__ 
sys.argv: ['wrapped_script.py', '--foo', '--bar=quux'] 

$ python3 wrapper.py --foo --bar=quux 
Executing the wrapped script... 
__name__: __main__ 
sys.argv: ['wrapped_script.py', '--foo', '--bar=quux'] 
+0

包裝腳本使用反斜槓延續時會失敗... –

相關問題