Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

モジュールの動的読み込み

More than 1 year has passed since last update.

なんとなくWebで見つけた今までの方法(imp.load_module)はdeprecatedだったため、Python 3.4におけるモジュールの動的読み込み処理を調べてみた。

ファイル構成

top
  |- main.py
  |- foo
          |- __init__.py
          |- some.py
          |- sample.py
  |- bar
          |- __init__.py
          |- some.py

古い方法

imp.load_module を使う方法で、find_module() の結果を使用してload_module() でモジュールを読み込む。
このとき、モジュール名(属性 __name__ )は load_module の第一引数nameが設定される。
Pythonではモジュールを sys.modules に登録するが、後勝ちになって先に読み込んだモジュールは上書きされてしまうことに注意する。
このため、fooとbarの両方のsome.pyを同じ名前someで読み込むと、意図しないものになることがある。

import sys
import imp

def load(dir_name:str, symbol:str): # -> module
    (file, path, description) = imp.find_module(dir_name + '/' + symbol)
    return imp.load_module(symbol, file, path, description)

m = load('foo', 'some')
m.__name__ # -> 'some'
sys.modules['some'] # -> 'module'

n = load('bar', 'some')
m == n # -> True

新しい方法

imp の置き換えとして importlib を使う。
importlib.import_module で、相対パスそのままでモジュールを読み込む。

import importlib

m = importlib.import_module('foo.some') # -> 'module'
m.__name__ # -> 'foo.some'

n = importlib.import_module('bar.some') # -> 'module'
n.__name__ # -> 'bar.some'

モジュール名を変えたいとき

古い方法と同様に、相対パス名を無視してモジュール名を自在に設定できるだろうか?
公式ドキュメントで imp.load_module の置き換えとして紹介されているものに次がある。
SourceFileLoader() を使い、その第一引数にモジュール名を設定することができる。
モジュール名(ここではsome)は、やはり後勝ちとなる。別の名前を設定することができるので、必要に応じて設定する。

import importlib.machinery as imm
datum = imm.SourceFileLoader('some', 'foo/some.py').load_module()

モジュール名の影響

foo/sample.pyでsome.pyを使用するとき、かつ動的に読み込む際の影響。
sampleを動的に読み込む場合、importで指定するモジュール名は sys.modules への登録名となる。上でモジュール名を変えていたときは、ここのimportにも影響する。

import some   # or
import foo.some

まとめ

  • Python 3.4 におけるモジュールの動的読み込みを調べた
  • importlibないしその配下のモジュールを使用する
  • モジュール名の扱いに注意する
progrommer
SEだけどプログラマー。実装とテストの自動化に興味あり。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away