yiskw note

機械学習やプログラミングについて気まぐれで書きます

【Python】モジュール内でそのモジュールへの参照を取得する


概要

Pythonを用いて,モジュール内で定義したクラスの一覧から,指定されたクラスのインスタンスを返す関数を,
そのモジュール内で作成しようとしておりました.

外部のモジュールであれば,以下のコードで実現が可能です.

import mod  # 自作モジュール


class_name = "Hoge"
# Hogeクラスのインスタンスを取得
instance = getattr(mod, class_name)()

このように,外部からあるモジュールを参照する場合はimportを行うだけで良いですが,
モジュール内部で自身への参照を取得する場合にはimportは使えません.
そこで,モジュール内でそのモジュールへの参照を取得する方法について調査したのでメモを残しておきます.

自身の参照を取得する方法1 importlib.import_module() / __import__()を使用する

モジュール内で自身の参照を取得するために,自身のファイル名を指定してimportすることを考えます.
モジュールの名前からimportを実行したい場合は,importlib.import_module(), もしくは__import__()を使用します.
以下のようにすることで,自身への参照を取得することができます.

import importlib


# importlib.import_moduleを使う場合
current_module = importlib.import_module(__name__)
# __import__を使う場合
current_module = __import__(__name__)

いずれでも結果は同じとなりますが,公式ドキュメントによると,

単純に名前からモジュール (パッケージの範囲内であるかも知れません) をインポートしたいなら、 importlib.import_module() を使ってください。

と書かれており,この場合はimportlib.import_module()の使用が推奨されております.

自身の参照を取得する方法2 sysを使用する方法

sysライブラリを使用することで,上記の方法と同様のことが行えます.

import sys


current_module = sys.modules[__name__]

完成したコード

  • mod.pyの中身
import importlib


class Hoge:
    def __init__(self, a=0, *args, **kwargs):
        self.a = a
        print(f"Instance of Hoge class with a = {a}")


class Foo:
    def __init__(self, b=0, *args, **kwargs):
        self.b = b
        print(f"Instance of Foo class with b = {b}")


def get_instance(class_name, *args, **kwargs):
    # instance = getattr(__import__(__name__), class_name)(*args, **kwargs)
    instance = getattr(importlib.import_module(__name__), class_name)(*args, **kwargs)
    return instance
  • main.pyの中身
from mod import get_instance

hoge = get_instance("Hoge", a=1, b=2)
foo = get_instance("Foo", a=1, b=2)
  • 実行結果
Instance of Hoge class with a = 1
Instance of Foo class with b = 2

Reference