[python]絶対パスでのモジュール追加方法

この辺を参考に、下記のようにすると、「E:\test_mod\addmodule.py」に置いたモジュールをインポート出来た。

#addmoduletest1.py

import importlib.util

MODULE_PATH = "E:\\test_mod\\addmodule.py"
MODULE_NAME = "addmodule"

spec = importlib.util.spec_from_file_location(MODULE_NAME, MODULE_PATH)
modulevar = importlib.util.module_from_spec(spec)
spec.loader.exec_module(modulevar)

modulevar.printingstatement()
#E:\test_mod\addmodule.py

def printingstatement():
      print("From addmodule.py")

しかし、下記のように、呼び出したモジュールで相対パスで独自定義モジュールを呼び出してる場合、このモジュールは正しく読み込まれなかった。

#E:\test_mod\addmodule.py
import mymod.py		#自作modを相対パスでインポート
def printingstatement():
      print("From addmodule.py")
      mymod.printmymod()
#E:\test_mod\mymod.py
def printmymod():
      print("From printmymod.py")
Traceback (most recent call last):
  File "E:\テスト\addmoduletest1.py", line 11, in <module>
    spec.loader.exec_module(modulevar)
  File "<frozen importlib._bootstrap_external>", line 883, in exec_module
  File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
  File "E:\test_mod\addmodule.py", line 2, in <module>
    import strcode
ModuleNotFoundError: No module named 'mymod'

mymodが無いって出てくる。モジュールファイル内で相対パスで別のモジュール読み込んでても、パスの起点はそれぞれのファイルからにはならないみたい。mainで実行しているscriptが起点になるので、自作モジュールライブラリがある場合、下記のようにパスを追加して使うのが正解みたい。

#addmoduletest2.py
import sys
MODULE_PATH = "E:\\test_mod"
sys.path.append(MODULE_PATH)
import addmodule

addmodule.printingstatement()

因みに、appendで追加したパスは、このスクリプト実行時のみ追加されます。

これが一番よさげ。

Cだと、#defineを#ifdefで複数回importしないようにとかやってたけど、pythonも似たような話あるんだろうか。appendは何度も実行すると、重複したパスが一杯入っちゃうし。複数回呼ぶ構成にする場合は、try import エラー出てたらexceptでappendしてからimportって感じか?

#addmoduletest3.py
import sys
try:
	import addmodule
except:
	print("except import")
	MODULE_PATH = "E:\\test_mod"
	sys.path.append(MODULE_PATH)
	import addmodule

addmodule.printingstatement()

しかし、いろんなファイルに、絶対パスが入るのは保守観点で良くないからこれはボツかな。自作ライブラリ使うなら、そのライブラリのパス通してから使うが基本ですね。addmoduletest2.pyの構成が正解でしょう。

参考

 

コメント

PAGE TOP
Ads Block Detector Powered by codehelppro.com
Ads Blocker Detected!!!

We have detected that you are using extensions to block ads. Please support us by disabling these ads blocker.

タイトルとURLをコピーしました