Pythonで別ファイルに定義されたモジュールやクラスを動的にロードして利用するにはimportlibモジュールのSourceFileLoaderメソッドを利用すると簡単に行うことができます。
例えばシステムによってロードするサブクラスを切り替えて利用すると言ったようなことが可能になります。
動的にモジュールやクラスをロードして利用する
Pythonでは動的にモジュールやクラスをロードして利用するにはimportlibモジュールのSourceFileLoaderメソッドを利用することで実現できます。
スーパークラスのソース
今回はスーパークラスを継承したサブクラスを用意して、そのサブクラスを別ファイルにして動的にロードして利用します。
まずはスーパークラスのソースから。
#SuperClass.py
class superClass :
def show( self ) :
print( "superClass.show() is called." )
動的にロードするサブクラスのソース
次に上記のスーパークラスをベースクラスとしたサブクラスのを用意します。
#SubClass.py
from SuperClass import superClass
class subClass1( superClass ) :
def show( self ) :
print( "subClass1.show() is called." )
class subClass2( superClass ):
def show( self ) :
print( "subClass2.show() is called." )
class subClass3( superClass ) :
#このクラスはスーパークラスのshow()を呼び出す
pass
class subClass4() :
#このクラスはスーパークラスsuperClassのサブクラスではないので処理対象外
def show( self ) :
print( "subClass4.show() is called." )
class subClass5( superClass ) :
def show( self ) :
print( "subClass5.show() is called." )
これで準備は完了です。
サブクラスを動的にロード
いよいよ、別ファイルにあるサブクラスを動的にロードします。
#main.py
import sys
import importlib.machinery as imm
import inspect
#スーパークラスをロードしておく
from SuperClass import superClass
#サブクラスのソースファイルをロードする
class_info = imm.SourceFileLoader( "subClass", "SubClass.py" ).load_module()
#ロードしたクラスで指定のスーパークラスのものだけ利用する
for load_class in superClass.__subclasses__() :
load_class().show()
まずは動的にソースファイルをロードするために
import importlib.machinery as imm
とモジュールをロードします。
実際には
class_info = imm.SourceFileLoader( "subClass", "SubClass.py" ).load_module()
でソースファイルをロードして
for load_class in superClass.__subclasses__() :
load_class().show()
「superClass」のサブクラスとしてロードされているものを順番に処理をすれば完成です。
上記のソースの実行結果は
subClass1.show() is called. subClass2.show() is called. superClass.show() is called. subClass5.show() is called.
になります。
「superClass」のサブクラスでないクラスは処理を対象外にしていますし、スーパークラスのメソッドも問題なくコールすることができます。
まとめ
この機能を上手く利用すれば汎用性が高くなり、他のシステムへの切り替えもサブクラスのソースだけを管理すればよいので見通しがよくなります。
以上、Pythonで動的にモジュールやクラスをロードして利用する方法でした。
