こちらの続きです。
動的にモジュールをインポートする1 - C#ATIA
もうちょっとFusion360のスクリプトっぽく考えました。
まず、"hoge.py" "piyo.py" "fuga.py" をそれぞれ作ります。
"hoge.py" の中身はこんな感じです。
# fusion360 API python # hoge.py import traceback import adsk.core import adsk.fusion def run(context): ui = None try: app = adsk.core.Application.get() ui = app.userInterface app.log('Hello hoge') except: if ui: ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
残りの2個はそれっぽく察して下さい。
狙いとしては、それぞれのエントリーポイントとなるrun関数を
動的に実行したいのです。
で、結局こんな感じです。
# fusion360 API python import traceback import adsk.core import adsk.fusion import sys import pathlib import importlib import inspect # このフォルダーをパスに追加 THIS_DIR = pathlib.Path(__file__).resolve().parent if str(THIS_DIR) not in sys.path: sys.path.append(str(THIS_DIR)) def run(context): ui = None try: app = adsk.core.Application.get() ui = app.userInterface # このフォルダ内の自身以外のpyファイルを取得 files = getPyFileNames() for file in files: # モジュールとしてインポート module = importlib.import_module(file.stem) importlib.reload(module) # モジュール内から関数名取得 funcs = [func for func, _ in inspect.getmembers(module, inspect.isfunction)] # run関数を持っていたら実行 if 'run' in funcs: module.run(context) # モジュールの破棄 del module except: if ui: ui.messageBox('Failed:\n{}'.format(traceback.format_exc())) def getPyFileNames() -> list: # 同じフォルダ内のpyファイルの取得 files = [f for f in THIS_DIR.iterdir() if f.is_file() and f.suffix == '.py'] # 自身は削除 files.remove(pathlib.Path(__file__).resolve()) return files
inspectを利用するとクラス名や関数名等が取得出来るのですね。優秀。
run関数を持っていたら、それを実行します。
画像あった方が目につくので、結果はこちら。
あぁCATIAで作ったあのメニューのFusion360版が作れる気がしてきた。
足音が聞こえてきた!