我想要做什么
我正在使用一個名為 MESA ( https://docs.mesastar.org/en/latest/index.html ) 的程式,每次運行的相關步驟是:
- 在文本檔案中使用輸入引數編輯幾行
- 執行 (bash) shell 命令“./mk”
- 執行 (bash) shell 命令“./rn”
在成功完成 rn 之后,這些步驟將在每次迭代中重復。
我的實作
為了自動化這些步驟,我想出了以下程式:
import subprocess
inputs[n][5] #2d array imported from csv
for i in range(len(inputs)):
#read data
with open('inlist', 'r', encoding='utf-8') as file:
data = file.readlines()
#lines to change
data[ 73] = “ RSP_mass = ” inputs[i][0] “d0\n”
data[ 74] = “ RSP_Teff = ” inputs[i][1] “d0\n”
data[ 75] = “ RSP_L = ” inputs[i][2] “d0\n”
data[ 99] = “ log_directory = 'LOGS/” inputs[i][3] “'\n”
data[100] = “ photo_directory = 'PHOTOS/” inputs[i][4] “'\n”
#write data
with open('inlist', 'r', encoding = 'utf-8') as file:
file.writelines()
#running MESA
subprocess.run(“./mk”)
subprocess.run(“./rn”, stdout = subprocess.PIPE)
問題一:
由于 MESA 的計算量非常大(使用了所有可用的 16 個執行緒)并且每次運行已經花費了 2 ? - 3 小時,我非常擔心可能出現的性能問題。由于每次運行的運行時間較長,因此也很難進行基準測驗。
有沒有更好的解決方案,我錯過了?
問題 2: 在運行期間,MESA 向 stdout 輸出的行數略少于 1000 行,我認為如果通過子行程運行,這會導致相當慢的速度。最簡單的方法當然是禁用任何輸出,但是能夠在運行期間檢查進化程序非常有用,所以我想盡可能保留它。從這個執行緒 Python: Reading a subprocess' stdout without printing to a file,我已經了解到 stdout=subprocess.PIPE 將是最快的方法。輸出資料的存盤已經由 MESA 自己處理。就性能而言,這是一個好的解決方案嗎?
問題3: 這是最不重要的問題,但它可能會影響之前問題的實施,所以我想我也會問一下。是否可以定義一個自定義鍵盤中斷,它不會立即終止程式,而只會在下一次運行完成后終止?基于執行緒如何生成鍵盤事件?我認為鍵盤庫最適合 Ubuntu。
uj5u.com熱心網友回復:
反復讀取和重寫輸入檔案既笨拙又低效,而且無論如何,在只讀模式下打開它時無法寫入('r')。
相反,我會讀取一個模板檔案,然后根據它撰寫實際的組態檔。Template(Python在標準庫中有一個單獨的類,可能值得研究,但這很簡單,可以從頭開始撰寫。)
一個子行程只是將 Python 完全排除在外,因此從 shell 運行任務的作業方式應該與從 Python 運行它們相同。
如果您沒有理由捕獲行程的輸出,只需讓它直接溢位到用戶的終端。沒有為stdout=和stderr=在subprocess呼叫中指定任何東西可以實作這一點。
import subprocess
# inputs[n][5] #2d array imported from csv
with open('template', 'r', encoding='utf-8') as file:
data = file.readlines()
for inp in inputs:
data[ 73] = f" RSP_mass = {inp[0]}d0\n"
data[ 74] = f" RSP_Teff = {inp[1]}d0\n"
data[ 75] = f" RSP_L = {inp[2]}d0\n"
data[ 99] = f" log_directory = 'LOGS/{inp[3]}'\n"
data[100] = f" photo_directory = 'PHOTOS/{inp[4]}'\n"
with open('inlist', 'w', encoding = 'utf-8') as file:
file.writelines()
subprocess.run("./mk", check=True)
subprocess.run("./rn", check=True)
注意它現在是如何從一個名為 的檔案中讀取的template,一旦在回圈之外,然后重復寫入 ( 'w') 。inlist我還修復了回圈,使其更加慣用,并將大彎雙引號更改為正確的 ASCII 雙引號。替代品現在使用 f 字串(恕我直言)提高了易讀性。在接近尾聲的時候,如果子行程失敗,check=True關鍵字引數 tosubprocess.run指示 Python 引發錯誤。
鍵盤中斷的想法聽起來很有挑戰性。q您可以添加一個信號處理程式來選擇性地忽略某些信號,但更簡單的解決方案是檢查是否在回圈中按下了任何常規鍵(或特定鍵;例如)。參見例如如何檢測按鍵?
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/485024.html
上一篇:將溫度從攝氏轉換為華氏?
