Pythonで別ファイルの関数やクラスを呼び出す方法|importの基本からパッケージ構成まで完全解説

目次

1. Pythonで別ファイルを呼び出す理由とメリット

プログラムが大きくなるほど、コードの分割が重要になる

Pythonを学び始めたばかりの頃は、1つのファイルにすべての処理を書いても問題ありません。しかし、コードが増えるにつれて、処理が複雑になり、1つのファイルで管理するのが難しくなってきます。

そこで重要になるのが、別ファイルに関数やクラスを分けて定義し、必要に応じて呼び出すという構造化の考え方です。これにより、コードが読みやすくなり、保守性や再利用性が格段に向上します。

コードの再利用性を高められる

たとえば、文字列を整形する関数や、日付をフォーマットする関数など、複数のスクリプトで繰り返し使いたい処理は多く存在します。こうした処理を別ファイルにまとめておけば、他のスクリプトでもimportするだけで簡単に利用できます。

# utils.py に定義
def format_date(date):
    return date.strftime('%Y-%m-%d')

# main.py から呼び出す
from utils import format_date

このようにすることで、一度書いたコードを何度でも使いまわせるため、作業効率が飛躍的にアップします。

保守性・可読性の向上

1つのファイルにすべての処理を書いてしまうと、バグが発生した場合に原因を特定するのが困難になります。また、他人がコードを読むときにも理解しづらくなります。

機能ごとにファイルを分けて管理すれば、

  • 「データベース処理はこのファイル」
  • 「ユーザー入力のバリデーションはこのファイル」

というように、責任の所在が明確になります。

結果として、

  • バグの修正が早くなる
  • チーム開発でもコンフリクトが減る
  • コードレビューがしやすくなる

というメリットが得られます。

本格的なプロジェクトでは必須のスキル

PythonでWebアプリケーションを作成する場合や、機械学習のモデルを複数管理するようなプロジェクトでは、ファイルを分割して機能を整理することが基本中の基本です。フレームワーク(DjangoやFastAPIなど)を使う際も、ディレクトリ構成とimportの概念を理解しておくことが前提になります。

そのため、Pythonの初学者であっても、「別ファイルから関数やクラスを呼び出す方法」は早い段階で身につけておくべき知識です。

2. Pythonの基本的なimport文の使い方

import文とは?

Pythonで他のファイル(モジュール)の関数やクラスを使いたいときに使うのが import 文です。
これを使えば、別ファイルに定義された処理を、まるでそのファイル内にあるかのように呼び出すことができます。

Pythonでは、この仕組みを使って標準ライブラリの機能を読み込んだり、自作したモジュールを使ったりできます。

同じフォルダ内のファイルを読み込む基本のimport

もっとも基本的な使い方は、同じディレクトリにある別のファイルを読み込む方法です。

たとえば、以下のような構成を考えてみましょう。

project/
├── main.py
└── utils.py

utils.py に定義された関数を main.py から使いたい場合、次のように記述します。

# utils.py
def greet(name):
    return f"こんにちは、{name}さん!"
# main.py
import utils

print(utils.greet("佐川"))

このように、ファイル名を指定するだけで、その中にある関数や変数を使えるようになります。
関数にアクセスするときは「モジュール名.関数名」の形式で記述します。

from-import構文で特定の関数だけを読み込む

特定の関数だけを使いたい場合は、from モジュール名 import 関数名 という形式で記述できます。

# main.py
from utils import greet

print(greet("佐川"))

このようにすれば、utils.greet() ではなく、greet() とシンプルに書けます。

なお、複数の関数をまとめてインポートする場合はカンマ区切りで記述できます。

from utils import greet, farewell

importに別名をつけて使う(エイリアス)

モジュール名が長い場合や、簡略化したい場合は、as を使ってエイリアス(別名)を指定できます。

import utils as ut

print(ut.greet("佐川"))

このようにすれば、コードを簡潔に保ちつつ、他のモジュールと衝突しないようにできます。

import文の書く場所に注意

Pythonでは、基本的に import 文はファイルの先頭に書くのが推奨されています。
ただし、例外的に一部のライブラリを使うタイミングでしか必要ない場合は、関数の中で書くことも可能です。

def use_numpy_temporarily():
    import numpy as np
    return np.array([1, 2, 3])

ただし、読みやすさや保守性を考えると、基本的には先頭にまとめて記述するのがベストプラクティスです。

年収訴求

3. サブディレクトリや他フォルダからのファイル呼び出し

Pythonではフォルダ構成によってimport方法が変わる

Pythonでスクリプトが複数のフォルダに分かれている場合、単純なimport文ではファイルを読み込めないケースが出てきます。
そのようなときは、正しいパス指定や仕組みの理解が必要です。

このセクションでは、サブディレクトリや他のフォルダにあるファイルの関数・クラスを呼び出す方法を、具体例とともに解説します。

サブディレクトリのファイルをインポートする

まず、以下のようなディレクトリ構成を想定します。

project/
├── main.py
└── tools/
    └── formatter.py

formatter.py にある関数を main.py から呼び出したい場合、基本的には以下のように書きます。

# tools/formatter.py
def shout(text):
    return text.upper() + "!"
# main.py
from tools import formatter

print(formatter.shout("hello"))

または、関数だけを使いたい場合:

from tools.formatter import shout

print(shout("hello"))

このように、サブディレクトリのファイルを呼び出すには「ディレクトリ名.ファイル名」という構文で指定します。

パッケージとして扱うには init.py が必要な場合もある

古いPython(3.2以前)や一部のツールでは、サブディレクトリをモジュール(パッケージ)として認識させるために __init__.py が必要です。

tools/
├── __init__.py
└── formatter.py

この場合、空の __init__.py ファイルを入れておくだけでOKです。Python 3.3以降では必須ではありませんが、入れておくと安心です。

親ディレクトリや兄弟フォルダのファイルをインポートする

今度は、別フォルダにあるファイルを呼び出す場合です。以下のような構成を考えてみましょう:

project/
├── main.py
└── modules/
    └── helper.py

この場合、Pythonはデフォルトでmodules/ディレクトリを検索対象として見てくれないため、次のような対策が必要です。

対策①:sys.pathを使ってパスを追加する

# main.py
import sys
import os
sys.path.append(os.path.join(os.path.dirname(__file__), 'modules'))

import helper

print(helper.some_function())

このようにして、Pythonのモジュール検索パスに任意のフォルダを追加できます。
特にスクリプトをプロジェクトのルートから実行する場合に有効です。

対策②:Pythonを実行する位置に注意する

Pythonのimportは実行する場所(カレントディレクトリ)に影響を受けます。
main.pyproject/ ディレクトリ内で実行しているか、それとも modules/ から実行しているかによって、importの成否が変わることがあります。

# 正しい実行方法
cd project
python main.py

また、VSCodeなどのエディタでは、「Pythonファイルとして実行」ボタンの動作が、スクリプト実行のパスに影響していることがあるため注意が必要です。

絶対パス vs 相対パスの違いに注意

  • from modules.helper import func のような記述は 絶対インポート
  • from ..modules import helper のような記述は 相対インポート

相対インポートは便利な反面、実行ファイルの位置によってエラーが出やすいです。
基本的には、絶対インポートを使うことが推奨されます。

4. 相対インポートと絶対インポートの違いと使い分け

Pythonのimportには2種類ある

Pythonで別ファイルを呼び出す際には、主に2つの方法があります。

  • 絶対インポート(absolute import)
  • 相対インポート(relative import)

この2つは目的は同じですが、書き方や使いどころが異なるため、状況に応じて正しく使い分けることが重要です。

絶対インポートとは?

絶対インポートは、プロジェクトのルートディレクトリからのパスでモジュールを指定する方法です。もっとも一般的で、多くのプロジェクトで推奨されている記法です。

from tools.formatter import shout

上記のように、「ディレクトリ名.ファイル名.関数名」という形式で指定します。

メリット

  • 読みやすく明確
  • 実行環境が変わっても安定して動作する
  • 他の開発者が構造を把握しやすい

デメリット

  • 長くなる場合がある(深い階層だと煩雑)

相対インポートとは?

相対インポートは、現在のファイル位置を基準にして、モジュールを指定する方法です。主にパッケージ内での内部モジュールの呼び出しに使われます。

from . import formatter          # 同じディレクトリ
from ..tools import formatter   # 1つ上のディレクトリ

.(ドット)は現在のディレクトリを、..(ドット2つ)は1つ上のディレクトリを示します。

メリット

  • パッケージ内での関係が明確
  • 同一パッケージ内での移動が柔軟にできる

デメリット

  • 実行ファイルの位置によってエラーが出やすい
  • 外部から直接実行するスクリプトには不向き
  • 複雑な構成では読みづらくなる

どちらを使うべき? 実務での使い分け方

一般的に、Python公式ドキュメントでも以下のように推奨されています:

  • ライブラリやプロジェクトの外部から呼び出すことを前提とする場合:絶対インポート
  • パッケージ内部での簡単なモジュール連携:相対インポート

また、初心者や小〜中規模のプロジェクトでは、絶対インポートを基本にするとトラブルが少なくて済みます。

実際のエラー例:相対インポートが動かない?

# example.py(単体で実行)
from .module import func  # ValueError: attempted relative import beyond top-level package

上記のように、相対インポートは単体のスクリプトとして実行するとエラーになることがあります。
これは、Pythonがそのファイルをパッケージとして認識していないためです。

この場合は、以下のようにモジュールとして実行することで回避できます。

python -m package.module

結論:基本は絶対インポート、状況によって相対インポート

  • 基本は絶対インポート(シンプルでわかりやすく、外部からの利用にも強い)
  • 同一パッケージ内での参照が多い場合に限って相対インポートを使う

相対インポートは便利ですが、スクリプトの実行方法や開発環境によって不安定になりやすいため、使いどころを見極めることが重要です。

RUNTEQ(ランテック)|超実戦型エンジニア育成スクール

5. モジュール管理のためのパッケージ化

複数のファイルを整理するには「パッケージ化」が有効

Pythonで規模の大きなプログラムを開発する場合、ファイルを適切に分割・整理することが非常に重要です。
このとき役立つのが「パッケージ化」という考え方です。

パッケージとは、モジュール(Pythonファイル)をディレクトリ単位でまとめたものです。複数の機能をグループ化することで、可読性・保守性・再利用性が大幅に向上します。

init.py の役割とは?

パッケージを構成するディレクトリには、原則として __init__.py というファイルを置く必要があります。

project/
└── tools/
    ├── __init__.py
    └── formatter.py

この __init__.py は、そのディレクトリを「Pythonにとってのパッケージである」と認識させるための目印です。
内容は空でも構いませんが、以下のようにモジュールの初期化処理を書いたり、外部に公開する関数を明示的に指定することもできます。

# tools/__init__.py
from .formatter import shout

これにより、呼び出し側は以下のように簡潔にインポートできます。

from tools import shout

ディレクトリ構成の例

実際にパッケージ化されたプロジェクトの構成例を見てみましょう。

my_project/
├── main.py
└── tools/
    ├── __init__.py
    ├── formatter.py
    └── validator.py

この場合、tools 以下の各モジュールはすべて main.py から呼び出すことができます。

# main.py
from tools import formatter, validator

print(formatter.shout("Hello"))
print(validator.is_valid("12345"))

パッケージ化のメリットまとめ

メリット内容
管理しやすい構造機能ごとにファイルを整理でき、見通しが良くなる
名前の衝突を避けられるモジュール名が被ることが少なくなる
再利用が容易になるパッケージごと別のプロジェクトでも使い回せる
単体テストや自動化がしやすいモジュール単位でテストを分けやすくなる

Python 3.3以降では init.py は省略可能?

Python 3.3 以降では、__init__.py がなくてもディレクトリをパッケージとして扱えるようになっています(Implicit Namespace Package)。
ただし、現実的には以下の理由で __init__.py を入れることが推奨されます。

  • ツールやライブラリによっては未対応のものがある
  • パッケージ内で明示的な初期処理を行いたいことがある
  • 可読性・明確さが上がる(人間にも分かりやすい)

そのため、__init__.py を使うのが今でも業界標準のベストプラクティスと言えるでしょう。

6. よくあるインポートエラーとその対処法

importに失敗する理由は、パスと構造の理解不足が多い

Pythonで別ファイルを呼び出そうとした際に、「モジュールが見つからない」「名前が定義されていない」などのエラーに悩まされる」という経験は、多くの初学者が通る道です。

ここでは、よくあるインポートエラーとその対処法を具体的に紹介します。

ModuleNotFoundError:モジュールが見つかりません

エラー例:

ModuleNotFoundError: No module named 'utils'

原因と対処法:

このエラーは、指定されたモジュールがPythonの検索パスに存在しないときに発生します。よくある原因は以下の通りです:

  • インポート対象のファイルが同じディレクトリや適切な位置に存在していない
  • 実行しているファイルの場所がパッケージ構成とずれている
  • sys.path にモジュールのパスが含まれていない

対処法:

  1. モジュールが存在するパスを確認する
  2. 実行するディレクトリをルートに統一する
  3. 必要に応じて sys.path.append() でパスを追加
import sys
import os
sys.path.append(os.path.join(os.path.dirname(__file__), 'modules'))

ImportError:モジュールはあるが、中身が読み込めない

エラー例:

ImportError: cannot import name 'greet' from 'utils'

原因と対処法:

このエラーは、モジュール自体は見つかっているが、指定された関数・クラス・変数などが見つからない場合に起きます。

主な原因:

  • ファイル名のタイプミス
  • 実際にはその名前の関数やクラスが存在しない
  • __init__.pyfrom .module import greet と書いていないため、外から見えない

対処法:

  • モジュール内に指定した名前が正しく存在するか確認
  • 大文字・小文字に注意(Pythonは区別します)
  • __init__.py に公開対象を明示する

相対インポートのエラー:ValueErrorやImportError

エラー例:

ValueError: attempted relative import beyond top-level package

原因:

このエラーは、相対インポートを使っているファイルを直接実行したときに発生します。Pythonはそのファイルを単独で実行した場合、それがパッケージの一部であると認識しません。

対処法:

  • 相対インポートを使う場合は、モジュールとして実行する必要があります。
# NG:直接実行
python script.py

# OK:モジュールとして実行
python -m package.script

インポートエラー回避のためのベストプラクティス

ポイント解説
スクリプトの実行場所を統一project/ をルートとし、VSCode等でも「作業ディレクトリ」を設定
import文は絶対パスで書く特に初心者は相対インポートを避けた方が安全
__init__.py を使って明示的に構成するパッケージ認識が確実になる
sys.pathを一時的に追加する場合は os.path で動的に指定環境の違いによる動作不良を回避できる
侍エンジニア塾

7. 実践コード例:別ファイルの関数を呼び出して使ってみよう

実際に手を動かして理解しよう

ここまでの解説で、Pythonで別ファイルを呼び出すための基本的な知識は身についたと思います。
しかし、「理解」と「使える」は別物です。

このセクションでは、実際に手を動かしながら、

  • ファイルの分割
  • import文の使い方
  • 関数の呼び出し方
    を学びましょう。

ステップ1:呼び出す関数を定義したファイルを作成する

まずは、呼び出される側のPythonファイルを作ります。

project/
├── main.py
└── utils.py

utils.py に、簡単な関数を定義しておきます。

# utils.py

def greet(name):
    return f"こんにちは、{name}さん!"

このファイルには、greet()という名前の関数が定義されています。
名前を引数に取り、挨拶のメッセージを返すシンプルな関数です。

ステップ2:呼び出し元のファイルからimportする

次に、メインの処理を行う main.py を作成します。

# main.py

import utils

message = utils.greet("佐川")
print(message)

このように、utils モジュールを import し、その中の greet() 関数を呼び出します。
ここでは、モジュール名 + 関数名という形式で使っています。

ステップ3:実行して結果を確認する

次に、ターミナルやコマンドプロンプトから main.py を実行してみましょう。

python main.py

出力結果:

こんにちは、佐川さん!

無事に別ファイルの関数が呼び出され、意図したメッセージが表示されました。

別のimport方法を試してみる(from-import)

以下のように書き換えることで、より簡潔に関数を呼び出すことも可能です。

# main.py(改良版)

from utils import greet

print(greet("佐川"))

この方法なら、utils.greet() ではなく、greet() とシンプルに書けます。

なお、複数の関数を使いたい場合は、カンマ区切りで列挙しましょう。

コードを整理するためのワンポイント

  • utils.py のような共通処理は、「modules」や「helpers」などのディレクトリにまとめると管理しやすくなります。
  • 実務レベルではディレクトリ構成を整えることが、読みやすさ・保守性の向上につながります

8. FAQ:Pythonの別ファイル呼び出しに関するよくある質問

Q1. importfrom ... import ... の違いは何ですか?

A.
どちらも別ファイルを読み込むための方法ですが、呼び出し方に違いがあります。

  • import module:モジュール全体を読み込み、module.function() のように使います。
  • from module import function:特定の関数やクラスだけを読み込み、function() のように直接呼び出せます。

複数の関数を使う場合や、明示的にどの関数を使っているかを見せたいときは from ... import ... が便利です。

Q2. 相対インポートがうまく動きません。なぜですか?

A.
相対インポートは、モジュールを単独で実行するとエラーになる場合があります。Pythonはそのファイルをパッケージの一部として認識しないためです。

以下のように、モジュールとして実行することで回避できます。

python -m package.module

また、初心者のうちは絶対インポートの使用をおすすめします。安定性が高く、トラブルが起きにくいためです。

Q3. Pythonでファイル構成をどうすればいいか迷います

A.
基本的には以下のように、機能ごとにディレクトリやモジュールを分ける構成が推奨されます。

project/
├── main.py
├── utils/
│   ├── __init__.py
│   ├── formatter.py
│   └── validator.py
└── config/
    └── settings.py
  • 複数の関数を含む場合はファイルを分割
  • 共通処理は「utils」や「common」などにまとめる
  • ディレクトリ単位でパッケージ化することで拡張しやすくなります

Q4. __init__.py は必ず必要ですか?

A.
Python 3.3以降では、__init__.py がなくてもパッケージとして機能するようになっています(Implicit Namespace Package)。
ただし、以下の理由で今でも使用が推奨されます。

  • 明示的にパッケージであることが分かる
  • 古いツールや一部のエディタでは必須
  • 初期化処理や公開関数の設定に使える

開発チームや商用開発でも広く採用されているので、基本的には常に設置する方が安全です。

Q5. import時に日本語や特殊文字を含むファイル名は使えますか?

A.
基本的にモジュール名(ファイル名)は英数字とアンダースコア(_)のみを使うべきです。

たとえば以下のようなファイル名はNGです:

  • 関数.py
  • utils-改.py

Pythonでは、ファイル名がそのままモジュール名になるため、特殊文字やハイフンはエラーの原因になります

正しい命名例:

  • utils.py
  • data_handler.py

9. まとめ:importを理解すればPythonはもっと自由になる

本記事で学んだことの振り返り

ここまでの記事では、次のような内容を段階的に解説してきました:

  • なぜ別ファイルを呼び出すのか?
     → コードを整理し、使いまわせるようにするため
  • 基本のimport文の使い方
     → import / from ... import ... の使い分け
  • サブディレクトリや別フォルダのモジュールの読み込み方
     → パスの扱いや__init__.pyの必要性も含めて理解
  • 絶対インポートと相対インポートの違い
     → 初心者には絶対インポートがおすすめ
  • よくあるインポートエラーとその対処法
     → エラー原因の多くは実行パスと構成ミス
  • 実践コードでの確認とFAQでの補足
     → 理論+実践+よくある質問までフォロー

importを使いこなせば、Pythonの世界が一気に広がる

importの仕組みを理解し、正しく使えるようになると、以下のようなメリットが得られます:

  • 大規模なプロジェクトでも迷わない構成が作れる
  • 共通処理をまとめて、保守や改修が楽になる
  • 他の人が書いたコードも理解しやすくなる
  • ライブラリやフレームワーク(Django、Flask、FastAPIなど)も自然に扱えるようになる

つまり、importの理解は、初学者から一歩抜け出すための登竜門とも言えるでしょう。

おわりに

Pythonはシンプルな文法と柔軟性が魅力ですが、その分「設計力」が問われる言語でもあります。
別ファイルの呼び出し方を正しく理解し、モジュールやパッケージを使いこなせるようになることで、あなたのコードは格段に進化します。

本記事が、あなたのPython学習や実務開発の一助になれば幸いです。
ぜひ、手を動かしながら、自分なりのモジュール構成を試してみてください。