探せば簡単に見つかるお話ですが、今後やろうと思っている事が
ある為、自身の理解の理解を深める為です。
通常、他のpyファイルから、クラスなり関数なりをインポートし
利用するのであれば、簡単です。
まずこのような面白味の一切ない "foo.py" を作成します。
# fusion360 API python # foo.py class Foo: def hello(self): print('hello')
Fooクラス内にはhelloメソッドのみがあります。
これを呼び出す為、同じフォルダ内にFusion360のスクリプトの
エントリーポイントとなるrun関数をこんな感じで作成すれば
OKです。
# fusion360 API python import traceback import adsk.core import adsk.fusion import sys import pathlib # このフォルダーをパスに追加 THIS_DIR = pathlib.Path(__file__).resolve().parent if str(THIS_DIR) not in sys.path: sys.path.append(str(THIS_DIR)) from .foo import Foo def run(context): ui = None try: app = adsk.core.Application.get() ui = app.userInterface Foo().hello() except: if ui: ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
"何もFusion360APIでやらなくたって・・・" とは感じますが、
検索してHitする内容と違う部分がありました。
通常のpythonの場合は、同じフォルダ内のpyファイルを
インポートする際は何も問題無いのですが、Fusion360の場合は
スクリプト自身のフォルダをsys.pathに追加しなければ、
エラーとなりました。
この辺が大人の事情なのでしょう。
ここからが本題。
このfooをインポートしている
from .foo import Foo
部分を・・何と言いますか、もっと大人な事情な方法で
呼び出しする事が出来ないかな?と思っています。
例えば、事前に "foo" だと分かっていない場合に
何かしらの方法で、文字として取得しモジュールとして
呼び出しできないか? と言う事です。
探した所、importlibなるものが標準ライブラリに
入っている事を知りました。
モジュールの動的読み込み - Qiita
同じような事を考える方々はいらっしゃるものです・・・。
実は、exec関数で強引な方法も試したのですが、グローバルな
部分に記載しなかれば機能しなかったり、あまりに暴力的なので
宜しくないとの事。
run関数をこんな感じで書き換えると、無事機能しました。
# fusion360 API python import traceback import adsk.core import adsk.fusion import sys import pathlib import importlib # このフォルダーをパスに追加 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 foo = importlib.import_module('foo') foo.Foo().hello() except: if ui: ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
メソッド名を調べる事も出来るものが、標準ライブラリに
入っていたのですが何だったかな・・・。