などで威力を発揮します。
アウトプロセス連携は単純です
下図のように「インプロセスのhmPython3」から「アウトプロセスとして別のPython」を起動し、 情報のやりとりは「shelve」ライブラリで行うというものです。
#DLL = loaddll( hidemarudir + @"\hmPython3.dll" ); #r = dllfuncw( #DLL, "DoString", "import inprocess"); freedll( #DLL );
インプロセスとなるhmPythonの役割は、
from hmPython import hm import shelve import subprocess # 秀丸のディレクトリ hidemarudir = hm.Macro.Var["hidemarudir"] # 現在実行しているマクロのディレクトリ currentmacrodirectory = hm.Macro.Var["currentmacrodirectory"] # アウトプロセスへと処理を(一部)委託する。そのPythonスクリプトのファイル名 outprocess_script = currentmacrodirectory + r'/outprocess.py' # アウトプロセスに処理を委託。 # アウトプロセスからインプロセスへと値を入れたいものは、shelveでやりとりする def call_subprocess(script_name, shelve_path): hmpython_exe = hidemarudir + r'/HmPython3/python.exe' startupinfo = subprocess.STARTUPINFO() startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW startupinfo.wShowWindow = subprocess.SW_HIDE result = subprocess.run((hmpython_exe, outprocess_script, shelve_path), startupinfo=startupinfo) return result # デバッグモニターや秀丸のアウトプット枠に対象データを表示 def dump_data(data): # デバッグモニタに表示 hm.debuginfo(type(data)) hm.debuginfo(data) # 秀丸のアウトプロセスに表示 output_result(type(data)) output_result(data) # 秀丸のアウトプット枠に出力する def output_result(msg): hm.Macro.Var["$_message"] = msg ret = hm.Macro.Eval(r''' // アウトプット枠へ出力 #OP = loaddll("HmOutputPane.dll"); #ret = dllfunc(#OP, "Output",hidemaruhandle(0), $_message + "\r\n"); freedll(#OP); ''') hm.Macro.Var["$_message"] = "" return ret # メイン def main_script(): # データやりとり用のshelveのパス。パッケージ名事態をシェルブの名前にしておく shelve_fullpath = currentmacrodirectory + '/' + __name__ # hmPythonだからこそ得やすいデータ param1 = len(hm.Edit.TotalText) # インプロセス側で持ったデータ multiarr = [ [1, 2, 3], [4, 5, 6], [7, 8, param1] ] #外部プロセスに渡すデータをシェルブにセーブ savedata = shelve.open(shelve_fullpath) # 自分から情報を格納する側がshelveをクリアする savedata.clear() # インプロセスからの情報をshelveに書き込んでいく savedata['from_inprocess_list'] = multiarr savedata.close() #----------------------------------------------------- # アウトプロセスとして別途pythonを呼び出す call_subprocess(outprocess_script, shelve_path=shelve_fullpath) #外部プロセスから渡されたデータをシェルブからロード load_data = shelve.open(shelve_fullpath) result_list = load_data["from_outprocess_list"] result_dict = load_data["from_outprocess_dict"] load_data.close() #----------------------------------------------------- dump_data(result_list) dump_data(result_dict) main_script()
アウトプロセスのPythonの役割は、
shelveライブラリを利用することで、 hmPythonと外部プロセスPythonの間で「データをパースする」 といった不毛な手間から解放されます。
import numpy as np import shelve import sys # 最初の引数には、shelveのフルパスが入っている shelve_fullpath = sys.argv[1] # インプロセス(hmPython側のpython)からshelveへと格納された情報を拾う。 data = shelve.open(shelve_fullpath) arg_list = data['from_inprocess_list'] data.close() result = np.array(arg_list) result = result.T # 転置行列 data = shelve.open(shelve_fullpath) # numpyのオブジェクトを直接代入すると、インプロセスの方でnumpyが勝手に読み込まれてしまう # それを防止するため、numpyの配列ではなく、あくまでも普通のpythonの多次元リストになおしておく data['from_outprocess_list'] = result.tolist() data['from_outprocess_dict'] = {"aaaa":33} data.close()