1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

sys.path.append()でモジュール探索パスを追加したがインポートができなかったのはpip installしたパッケージが原因だった

Posted at

概要

自作モジュールを相対パスでimportしたく、sys.path.append(os.path.dirname(__file__)を入れたのに何故かimportができなかった。

結論

pipで入れていたパッケージと自作モジュールで利用していた名前が被っていたため、pipで入れたパッケージを読み込みにいってしまっていた。

環境

  • Windows10
  • miniconda

詳細

以下のような構成で自作モジュールを呼び出そうとしたところ、libs.utilsが見つからないとModuleNotFoundErrorが発生。

parent_dir/
  |- my_modules/
  |   |- libs/
  |      |- utils.py
  |   |- my_module.py
  |- controller.py

controller.pymy_module.pyutils.pyと呼び出す流れ。

各モジュールのコード

controller.py
from my_modules.my_module import *

module_func()
my_modules\my_module.py
from libs.utils import *

def module_func():
    print("This is module_func")
    utils_func()
my_modules\libs\utils.py
def utils_func():
    print("This is utils_func")

やりたいこと

parent_dirにいる状態でpython controller.pyを実行
⇒以下のような結果が欲しい。

AnacondaPrompt
[自分のフォルダ]\parent_dir>python controller.py
This is module_func
This is utils_func

しかし、結果は以下の通り。

AnacondaPrompt
  File "[自分のフォルダ]\parent_dir\my_modules\my_module.py", line 1, in <module>
    from libs.utils import *
ModuleNotFoundError: No module named 'libs.utils'

原因と解決策

原因:コマンドから実行する場合、controller.pyを実行しているparent_dirが基準になるため、parent_dirからlibs.utilsを探しているが見つからない。
解決策こちらの記事を参考に「モジュール探索パスを追加して絶対インポート」する方法を実践。

つまり、my_modules\my_module.pysys.path.append(os.path.dirname(__file__)を追加する。

my_modules\my_module.py
# 追加分
import os
import sys
sys.path.append(os.path.dirname(__file__))
# 追加分ここまで
from libs.utils import *

def module_func():
    print("This is module_func")
    utils_func()

これにより、my_moduleフォルダもパスに追加されるため、相対パスとして読み込んでくれるはず!

結果

AnacondaPrompt
  File "[自分のフォルダ]\parent_dir\my_modules\my_module.py", line 1, in <module>
    from libs.utils import *
ModuleNotFoundError: No module named 'libs.utils'

変わらない!なぜ!

現象の調査

いろいろ試してみると、自分が使っているminicondaの仮想環境でこの事象が発生することが判明。(新規作成したまっさらな仮想環境では事象が発生しない。)

試したこと

仮想環境にinstallした何かしらのパッケージが原因と考え、問題環境のinstallパッケージの一部を削除しながら原因のパッケージを特定することに。
おそらく他に効率が良いやり方があるのだろうが、知識のない私は地道な作業で調査。
※以下のコマンドはこちらを参考にさせていただきました。

①仮想環境の情報をyamlファイルに書き出す。

AnacondaPrompt
conda env export > ファイル名.yml

②yamlファイルのうちdependenciesを2分探索の要領で分割
③分割したyamlファイルを基に新規環境作成

AnacondaPrompt
conda env create -n 新たな環境名 -f ファイル名.yml

特定

そしてついに突き止めた。

env.yaml
dependencies:
  - pip=21.2.4=pyhd8ed1ab_0
  - pip:
    - libs==0.0.10

このlibsが存在していると問題が発生する。

ここまでくれば原因は明確。
libs.utilsを見に行く際に、pipでinstallしているlibsを優先的に探していたということであった。

教訓

  • 自作モジュールを使う場合は汎用的な命名を避ける。(my_libsのような名前にする。)
  • condaとpip:混ぜるな危険←今回は直接関係なかったが、改めて確認するとpip installしているパッケージが多かったと反省。
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?