Pythonのimportで相対パスを指定する方法

【Python】importで相対パスを指定する方法

公開: 更新:
CodeCampが提供するDX人材育成が可能なプログラミングやITが学べる公開講座

Pythonプロジェクトの規模が大きくなると、ファイルを複数のディレクトリに分けて管理する場面が増えます。その際、パッケージ内部のモジュール同士を参照するために、相対パスを使ったimportが役立ちます。

相対パスによるimportとは、現在のモジュールが属するパッケージを基準にして、ドット表記(.や..)で参照先のモジュールを指定する方法です。完全修飾名(パッケージ名.モジュール名)を書かずに済むため、パッケージ内部のモジュール間で簡潔にimportできます。

この記事では、Pythonのimportで相対パスを指定する基本的な書き方から、よくあるエラーの対処法まで、ディレクトリ構成例とサンプルコード付きで解説していきます。



Pythonのimportで相対パスを指定する方法

Pythonの相対importを使うには、fromにドット(.)を付けてモジュールの位置を示します。ドット表記は、現在のモジュールが属するパッケージを基準とし、ドット1つ(.)が現在のパッケージ、ドット2つ(..)が親パッケージを表す記法です。基本的な書き方は、以下の通りです。

from . import module_name       # 同じパッケージ内のモジュール
from .. import module_name      # 親パッケージ内のモジュール
from .sub_package import module_name  # サブパッケージ内のモジュール

なお、相対importは必ずfrom文と組み合わせて使います。import .utilsのように単独のimport文で書くとSyntaxErrorが発生するため注意してください。

また、相対importはパッケージの一部として読み込まれたモジュールからしか使用できません。通常は__init__.pyを配置したディレクトリをパッケージとして扱いますが、Python 3.3以降では__init__.pyがなくても名前空間パッケージとして認識されます(詳細はFAQを参照)。ここでは、以下の3つのパターンを解説します。

  1. 同じパッケージ内のモジュールをimportする
  2. 親パッケージのモジュールをimportする
  3. サブパッケージのモジュールをimportする

それぞれのパターンで使用するドット表記が異なるため、パッケージ構成に応じた使い分けが重要です。

それでは各パターンについて、解説していきます。

同じパッケージ内のモジュールをimportする

同じパッケージ内にあるモジュールをimportする場合は、ドット1つ(.)を使います。以下のディレクトリ構成を前提に、具体的な書き方を確認しましょう。

project/
├── __init__.py
├── main.py
└── utils.py    # このモジュールをimportしたい

上記の構成で、main.pyからutils.pyをimportするコードは以下の通りです。

# main.py
from . import utils

# utils内の関数を使用
result = utils.calculate(10, 20)
print(result)

上記のコードでは、from . import utilsのドット(.)が「現在のモジュールが属するパッケージ」を意味しています。これにより、main.pyと同じパッケージにあるutils.pyモジュール全体をimportします。

モジュール内の特定の関数やクラスだけをimportしたい場合は、以下のように記述します。

# main.py
from .utils import calculate

# 直接関数を呼び出せる
result = calculate(10, 20)
print(result)

上記のコードでは、from .utils import calculateでutils.py内のcalculate関数だけをimportしています。この書き方を使うことによって、utils.calculate()ではなくcalculate()と直接呼び出せるようになります。

なお、このファイルをpython main.pyのように直接実行するとエラーが発生します。実行方法については後述の「no known parent packageエラーの対処法」で詳しく解説します。

親パッケージのモジュールをimportする

親パッケージにあるモジュールをimportする場合は、ドット2つ(..)を使います。以下のディレクトリ構成を前提に確認しましょう。

project/
├── __init__.py
├── config.py       # このモジュールをimportしたい
└── sub_package/
    ├── __init__.py
    └── handler.py  # ここからconfig.pyをimportする

上記の構成で、handler.pyから親パッケージのconfig.pyをimportするコードは以下の通りです。

# sub_package/handler.py
from .. import config

# config内の変数を使用
db_host = config.DATABASE_HOST
print(db_host)

上記のコードでは、from .. import configのドット2つ(..)が「1つ上の階層のパッケージ」を意味しています。handler.pyの親パッケージであるproject直下のconfig.pyをimportします。

理論上は、ドット3つ(...)以上を使ってさらに上位のパッケージを参照することもできます。ただし、ドット3つ以上を使う相対importはコードの可読性が著しく下がるうえ、後述する「beyond top-level packageエラー」も発生しやすくなります。そのため、実務では深い階層を遡る場合は絶対importに切り替えるのが一般的です。


Python研修一覧はこちら

目的に合うPython研修を一覧形式から探したい方は、ぜひご利用ください。

Python研修を比較する

Java研修一覧はこちら

目的に合うJava研修を一覧形式から探したい方は、ぜひご利用ください。

Java研修を比較する

PHP研修一覧はこちら

目的に合うPHP研修を一覧形式から探したい方は、ぜひご利用ください。

PHP研修を比較する

新入社員研修

目的に合う新入社員研修を一覧形式から探したい方は、ぜひご利用ください。

新入社員研修を比較する

全ての研修からも探したい方はこちら

サブパッケージのモジュールをimportする

サブパッケージ(子パッケージ)内のモジュールをimportする場合は、ドット1つ(.)にサブパッケージ名を続けて記述します。以下のディレクトリ構成を前提に確認しましょう。

project/
├── __init__.py
├── main.py         # ここからサブパッケージのモジュールをimportする
└── helpers/
    ├── __init__.py
    └── formatter.py  # このモジュールをimportしたい

上記の構成で、main.pyからhelpers/formatter.pyをimportするコードは以下の通りです。

# main.py
from .helpers import formatter

# formatter内の関数を使用
text = formatter.format_date("2026-04-20")
print(text)

上記のコードでは、from .helpers import formatterでサブパッケージhelpersの中にあるformatter.pyをimportしています。ドット(.)は現在のパッケージを示し、そこからhelpersパッケージ内のformatterモジュールを参照します。

サブパッケージ内の特定の関数を直接importすることも可能です。

# main.py
from .helpers.formatter import format_date

# 直接関数を呼び出せる
text = format_date("2026-04-20")
print(text)

上記のコードでは、from .helpers.formatter import format_dateでformatter.py内のformat_date関数だけをimportしています。ドット区切りでパッケージ階層をたどることによって、ネストされたパッケージ内のモジュールにもアクセスできます。

Pythonの相対パスimportで発生するエラーの対処法

Pythonの相対importでは、実行方法やパッケージ構成によってエラーが発生することがあります。ここでは、相対import特有で特によく遭遇する2つのエラーについて、原因と対処法を解説します。

  1. no known parent packageエラーの対処法
  2. beyond top-level packageエラーの対処法

どちらのエラーもPythonのパッケージ構造に関する仕様が原因であり、正しい実行方法を理解することによって解決できます。

それでは各エラーについて、解説していきます。

no known parent packageエラーの対処法

ImportError: attempted relative import with no known parent packageは、相対importを使ったファイルを直接実行した場合に発生するエラーです。

# main.py を直接実行するとエラーになる
# python main.py  ← この実行方法ではエラー

from . import utils  # ImportError が発生

このエラーの原因は、Pythonが直接実行されたファイルに対して親パッケージの情報を与えないことにあります。ファイルをpython main.pyで直接実行すると、そのファイルのモジュール名(__name__)は__main__となり、親パッケージを示す__package__属性はNoneになります。相対importは__package__を基準に解決されるため、これが設定されていないとimportできずエラーになります。

このエラーを解決するには、-mオプションを使ってモジュールとして実行します。以下のように、プロジェクトの親ディレクトリからpython -m パッケージ名.モジュール名の形式で実行してください。

# ディレクトリ構成:
# workspace/
# └── project/
#     ├── __init__.py
#     ├── main.py
#     └── utils.py

# workspace/ で以下を実行
python -m project.main

-mオプションで実行すると、対象ファイルはパッケージの一部としてロードされ、__package__属性に親パッケージ名(この例ではproject)が設定されます。これによってパッケージ文脈が与えられ、main.py内の相対importが正しく解決されるようになります。

なお、どうしても直接実行したい場合や、より可搬性の高いコードにしたい場合は、相対importを絶対importに書き換えるのも有効な解決策です。

beyond top-level packageエラーの対処法

attempted relative import beyond top-level packageというメッセージのエラー(Pythonのバージョンや実行状況によってValueErrorまたはImportErrorとして発生)は、ドット表記でトップレベルパッケージより上の階層を参照しようとした場合に発生します。

ここで言うトップレベルパッケージとは、Pythonが実行時にsys.pathから認識できる最上位のパッケージのことです。必ずしもプロジェクトの最上位ディレクトリと一致するわけではなく、実行方法によって変わる点に注意してください。

# ディレクトリ構成:
# project/
# ├── __init__.py
# └── sub_package/
#     ├── __init__.py
#     └── module_a.py

# module_a.py で以下を書くとエラー
from ... import something  # トップレベルパッケージの外を参照しようとしている

上記のコードでは、module_a.pyからドット3つ(...)で2つ上のパッケージを指定しています。module_a.pyはsub_package内にあるため、1つ上はproject、2つ上はprojectの外側になります。projectがトップレベルパッケージの場合、その外側は参照できないためエラーが発生します。

このエラーを解決するには、パッケージ構成を見直すか、絶対importに切り替える必要があります。以下の2つの方法が有効です。

# 方法1: ドットの数を減らして、パッケージ階層内に収める
from .. import config  # 1つ上のパッケージ(project直下)まで

# 方法2: 絶対importに切り替える
from project import config  # トップレベルからの完全修飾名で指定

上記のように、ドットの数がパッケージの階層を超えないように調整するか、絶対importに切り替えることによってエラーを回避できます。実務では、深い階層からの相対importが必要になった場合は、絶対importを使う方がコードの可読性も高くなります。


Python基礎・実践(Django)

企業・法人向けのPython研修では、基礎から応用まで体系的に学べます。

Python研修の詳細

DX社員研修

企業・法人向けのDX研修では、実務に繋がるリスキリングでITレベルを向上させます。

DX研修の詳細

Javaエンジニア育成研修

企業・法人向けのJavaエンジニア育成研修では、Javaの基礎から応用まで確実に習得できます。

Java研修の詳細

新卒・新入社員向け研修

企業・法人に新入社員・新卒社員に向けたプログラミング研修を提供しています。

新入社員研修の詳細

コードキャンプのIT研修を全て見る

Pythonの相対パスimportに関するよくある質問

__init__.pyは必要ですか?

Python 3.3以降では、__init__.pyがなくてもディレクトリをパッケージとして認識する「名前空間パッケージ」という仕組みが導入されているため、必須ではありません。ただし、通常のアプリケーション開発では__init__.pyを配置することが推奨されます。

  • __init__.pyあり: 通常パッケージとして認識される
  • __init__.pyなし: 名前空間パッケージとして扱われる

__init__.pyを配置することによって、パッケージの初期化処理を定義したり、パッケージの公開APIを明示したりできます。また、パッケージの境界が明示的になり、単一ソースツリーのアプリケーションでは挙動を把握しやすくなります。特別な理由がない限り配置しておきましょう。

相対パスと絶対パスのどちらを使うべきですか?

Pythonの公式スタイルガイド(PEP 8)では、絶対importの使用が推奨されています。ただし、明示的な相対importも許容される代替手段として位置付けられています。

Absolute imports are recommended, as they are usually more readable and tend to be better behaved (...).
However, explicit relative imports are an acceptable alternative to absolute imports, especially when dealing with complex package layouts where using absolute imports would be unnecessarily verbose.

(絶対importは通常読みやすく挙動も安定しているため推奨されます。ただし、複雑なパッケージ構成で絶対importを使うと冗長になる場合には、明示的な相対importも許容される代替手段となります。)

出典: PEP 8 – Style Guide for Python Code

絶対importと相対importの特徴を整理すると、以下のようになります。

import方法 メリット デメリット
絶対import モジュールの位置が明確で可読性が高い パッケージ名を変更すると修正箇所が増えやすい
相対import 記述が簡潔でパッケージ名の変更に強い パッケージ構成の変更時に修正が必要になりやすい

基本方針としては絶対importを第一候補としつつ、パッケージ内部で記述が冗長になる場合は相対importも併用する、という使い分けが現実的です。

sys.path.appendを使った方法は推奨されますか?

sys.path.append()を使ってモジュール検索パスに手動でディレクトリを追加する方法は、アプリケーション本体やライブラリコードでは推奨されません。

  • 環境依存のパスをコードに埋め込むことになる
  • 他の開発者が同じ環境を再現できない可能性がある
  • パッケージ構成を正しく設計すれば不要になる

ただし、一時的な検証スクリプトやJupyter Notebookでの開発など、可搬性が重視されない場面で使われることはあります。通常の相対importでエラーが発生した場合は、sys.path.appendに頼るのではなく、python -mオプションでモジュールとして実行する、あるいは絶対importに書き換える方法を優先してください。

※上記コンテンツの内容やソースコードはAIで確認・デバッグしておりますが、間違いやエラー、脆弱性などがある場合は、コメントよりご報告いただけますと幸いです。

ITやプログラミングに関するコラム


ITやプログラミングに関するニュース

ブログに戻る

コメントを残す

コメントは公開前に承認される必要があることにご注意ください。

企業・法人向けのIT・プログラミング・生成AI研修を探す、比較する - IT・プログラミングを知って学べるコネクトメディア CodeCampが提供するDX人材育成が可能なプログラミングやITが学べる公開講座 - IT・プログラミングを知って学べるコネクトメディア コードキャンプが提供する無料で学べるプログラミングスクール講座 - IT・プログラミングを知って学べるコネクトメディア コードキャンプDX人材育成研修 - IT・プログラミングを知って学べるコネクトメディア 3.5日の研修で、年間1,600時間の削減効果が見込まれる。東京きらぼしフィナンシャルグループのDX人材育成事例 - IT・プログラミングを知って学べるコネクトメディア 配属3ヶ月で30%の生産性向上を実現するいよぎんコンピュータサービスの新人研修に迫る - IT・プログラミングを知って学べるコネクトメディア 金融業界の業務効率化を加速するニッセイアセットマネジメントの生成AI×GAS活用研修事例 - IT・プログラミングを知って学べるコネクトメディア 【製造業のDX人材育成事例】デジタル人材の即戦力化を実現する、日本ガイシ株式会社の異動者向オンボーディング研修 - ITやプログラミングを知って学べるコネクトメディア フューチャーアーキテクト株式会社が実現した新入社員向けIT研修プログラムでタスクフォース制度が主体的な学びと成長を生み出す - IT・プログラミングを知って学べるコネクトメディア コードキャンプDX人材育成研修 - IT・プログラミングを知って学べるコネクトメディア コードキャンプIT・プログラミング研修事例/【IT新入社員研修】オンラインとオフラインの最適バランスを実現したFutureOneの導入事例 - IT・プログラミングを知って学べるコネクトメディア コードキャンプIT・プログラミング研修事例/【新入社員研修】柔軟なハイブリッド型Java研修で実現した新卒20名の成長と成果|サークレイス株式会社 - ITやプログラミングを知って学べるコネクトメディア コードキャンプIT・プログラミング研修事例/現場により近いところにデジタルを根付かせるDX基礎講座研修|株式会社ブリヂストン - ITやプログラミングを知って学べるコネクトメディア コードキャンプIT・プログラミング研修事例/業務の効率化・DX推進に向けたIT人材育成への第一歩|株式会社カナエ - ITやプログラミングを知って学べるコネクトメディア 企業・法人向けのIT・プログラミング研修 - ITやプログラミングを知って学べるコネクトメディア

新着記事

対象者別で探す

子供(小学生・中学生・高校生)向け
プログラミング教室検索する

子供(小学生・中学生・高校生)がロボットやプログラミング言語を学ぶことができるオフラインからオンラインスクールを検索、比較することが可能です。

子供(小学生・中学生・高校生)
プログラミング教室検索する

ITやプログラムなどの
最新情報を検索する

日々、新しいITやプログラミング言語の情報が流れていきますが、特定の情報を時系列でニュースやコラムを確認することができます。

ITやプログラムなどの
最新情報を検索する