Pythonプロジェクトのカスタムモジュールインポートエラー解決方法

問題の概要

プロジェクト「great_gas_or_agents」のディレクトリ構成は以下の通りです:

- log_data_extract 
    - main.py
- math_algorithm

main.pyを実行すると、以下のエラーが発生します:

from math_algorithm.utils import parse_month_match_request
ModuleNotFoundError: No module named 'math_algorithm'

os.getcwd()を出力すると、結果は以下のようになります:

C:\Users\pengkangzhen\PycharmProjects\wk-projects\great_gas_or_agents\log_data_extract

問題の原因

以下のようなディレクトリ構造を例に説明します:

project/
│
├── main.py
├── data/
│   └── datafile.txt
└── scripts/
    └── script.py

現在の作業ディレクトリがproject/の場合、main.pyでdatafile.txtを読み込む際の相対パスはdata/datafile.txtとなります。ターミナルではpython ./main.pyを実行できます。

別のディレクトリ構造を考えてみましょう:

project/
│
├── script.py
├── data/
│   └── datafile.txt
└── scripts/
    └── main.py

main.pyでos.getcwd()を出力すると、実行時の現在の作業ディレクトリはproject/となります。main.pyでdatafile.txtを読み込む相対パスは./data/datafile.txtであり、../data/datafile.txtではありません。相対パスは現在の作業ディレクトリを起点とするためです。

main.pyのコード例:

with open("./data/datafile.txt", 'r', encoding="utf-8") as f:
    data = f.read()
print(data)

ターミナルでpython ./scripts/main.pyを実行すると、datafile.txtの内容が出力されます。

main.pyで他のモジュール(script.pyのprocess_dataメソッド)をインポートする場合:

import script
with open("./data/datafile.txt", 'r', encoding="utf-8") as f:
    data = f.read()
print(data)
script.process_data()

ターミナルでpython .\\scripts\\main.pyを実行すると、ModuleNotFoundError: No module named 'script'というエラーが発生します。Pythonインタプリタの現在の作業ディレクトリはproject/ですが、project/は自動的にsys.pathに追加されないためです。

解決方法

方法1:相対インポートの使用

project/ディレクトリに__init__.pyファイル(空ファイルでも可)を配置し、パッケージとして認識されるようにします:

project/
│
├── __init__.py
├── script.py
├── data/
│   └── datafile.txt
└── scripts/
    ├── __init__.py
    └── main.py

プロジェクトのルートディレクトリから-mオプションを使用して実行します:

python -m scripts.main

方法2:sys.pathの修正

scripts/main.pyでsys.pathを手動で修正し、プロジェクトのルートディレクトリを追加します:

import os
import sys

# プロジェクトルートディレクトリを取得
root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
# プロジェクトルートディレクトリをsys.pathに追加
sys.path.append(root_path)

import script

with open("./data/datafile.txt", 'r', encoding="utf-8") as f:
    data = f.read()
print(data)
script.process_data()

これでpython .\\scripts\\main.pyを実行できるようになります。

方法3:環境変数の使用

1. VSCodeでCtrl+`(バッククォート)を押してターミナルを開くか、View > Terminalから開きます

2. PYTHONPATH環境変数を設定します:$env:PYTHONPATH="C:\Users\pengkangzhen\PycharmProjects\wk-projects\great_gas_or_agents"

3. main.pyを実行します

launch.jsonの設定

コードの実行は可能ですが、デバッグにはlaunch.jsonの設定が必要です:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Python Debugger: Current File",
            "type": "debugpy",
            "request": "launch",
            "program": "${file}",
            "console": "integratedTerminal"
        }
    ]
}

タグ: Python VS Code モジュールインポート sys.path PYTHONPATH

6月2日 21:14 投稿