Python3でのmodule import

Python3 import

2022.12.08

はじめに

Python3でのimport文, fromや__init__.pyなどに若干の苦手意識があったため整理しました。


用語

  • module 1つの機能単位. 1ファイルに相当.
  • package moduleの集まり. 1ディレクトリに相当.

基本的な使い方

ファイル構成

自作モジュール, パッケージをimportする状況を考えます.

ファイル構成は以下の通り

Shell
$ tree -L 2
.
├── pkg
│   └── hola.py
├── hello.py
└── main.py

import module名

最も基本的なimport方法で, module名の後にasで別名をつけることができます。自作の場合はmodule名はファイル名と同じで, 普通importできるのは同じディレクトリ内のmoduleのみ。import <package名>.<module名>となる場合もあります。

Python3
HELLO="hello!"
Python3
import hello

print(hello.HELLO)
Shell
hello!

from <X> import <Y>

X Y
package名 module名
module名 識別子

などのパターンがあります。

Python3
HOLA="hola!"
Python3
from pkg import hola

print(hola.HOLA)

他にも

Python3
import pkg.hola

print(pkg.hola.HOLA)

Python3
from pkg.hola import HOLA

print(HOLA)

とも書けます


任意のディレクトリにあるmoduleをimport

次は別のディレクトリ構成にしてみます

Shell
$ tree -L 2
.
├── pkg1
│   ├── hola.py
│   └── __init__.py
└── pkg2
    └── main.py
Python3
import sys
import os
sys.path.append(os.path.abspath('path/to/src'))
import hola

print(hola.HOLA)

sys.pathはimportするmoduleへのパスのリストです。別のディレクトリからmoduleをimportする場合はこのlistにpathをマニュアルで加えます。


結局__init__.pyはなんのためにあるのか

__init__.pyとは

 __init__.pyというのはpackageが読み込まれる際の一番初めに実行されるファイルです。packageを作る際に必要ですが, ややこしいのはPython3.3の名前空間パッケージという機能追加のせいで__init__.pyがなくてもパッケージとして利用できるようになった点です。
名前空間パッケージは同じ名前のディレクトリが別のpathに存在する際にひとつのパッケージにまとめるといった特殊な用途で使うもので, 通常は__init__.pyを置いた方がよいです。


__init__.pyの利用例

 空のファイルを置くだけだと存在意義がよく分からなくなりそうなので実際に__init__.pyを使う例として, 環境変数ENVがdevelopmentかproductionかでmoduleを分けるような場合を考えてみます。

Shell
$ tree -L 2                                                           
.
├── pkg1
│   ├── __init__.py
│   ├── dev_logger.py
│   └── prod_logger.py
└── pkg2
    └── main.py
Python3
from dotenv import laod_dotenv
import os

if os.environ.get("ENV")=="production":
  from . import prod_logger as logger
else:
  from . import dev_logger as logger

 このようにするとmainからはpkg1のloggerを読み込むだけで環境変数に応じたmoduleを使うことができます。
 他にも__all__という変数を定義することでfrom pkg import *としたときに読み込むmoduleを設定するのによく使われているようです。


参考文献

Python3のimportパターン13個
Pythonの__init__.pyとは何なのか