importlib (Python Dynamic import)
출처: https://bluese05.tistory.com/31 [ㅍㅍㅋㄷ:티스토리]
https://light-tree.tistory.com/8
http://til.junshoong.net/python/import-module-function
importlib
사용자가 파이썬의 임포트 시스템과 상호작용하기 위한 API를 제공하는 내장 라이브러리
importlib.import_module()
__import__()의 래퍼함수
np = importlib.import_module("numpy")
import importlib # 111 # import dashPages # from dashPages.basic_boxes import view # from dashPages.basic_boxes import callbacks # from dashPages.basic_boxes import model # 2222 # view = importlib.import_module('dashPages.basic_boxes.view') # callbacks = importlib.import_module('dashPages.basic_boxes.callbacks') # model = importlib.import_module('dashPages.basic_boxes.model') # 333 myModule = 'basic_boxes' view = importlib.import_module(f'dashPages.{myModule}.view') callbacks = importlib.import_module(f'dashPages.{myModule}.callbacks') model = importlib.import_module(f'dashPages.{myModule}.model')
예제
python에서 숫자 등으로 시작하는 패키지를 import 할때는 주의해야한다.
import 1234 from 1234 import abc
import importlib #importlib.import_module('1234') p = importlib.import_module('1234') p.abc()
예제
기본적으로 import 사용
import 팩키지.모듈 as 별명
import dashPages.value_boxes.view as value_boxes import dashPages.basic_cards.view as basic_cards import dashPages.social_cards.view as social_cards import dashPages.tab_cards.view as tab_cards import dashPages.basic_boxes.view as basic_boxes
별명 = importlib.import_module(‘패키지.모듈’)
value_boxes = importlib.import_module('dashPages.value_boxes.view') basic_cards = importlib.import_module('dashPages.basic_cards.view') social_cards = importlib.import_module('dashPages.social_cards.view') tab_cards = importlib.import_module('dashPages.tab_cards.view') basic_boxes = importlib.import_module('dashPages.basic_boxes.view')
함수사용
case1
def load_module(module_nm): rlt = importlib.import_module(f"dashPages.{module_nm}.view") return rlt value_boxes = load_module('value_boxes') basic_cards = load_module('basic_cards') social_cards = load_module('social_cards') tab_cards = load_module('tab_cards') basic_boxes = load_module('basic_boxes')
case 2
def load_module(module_nm): rlt = importlib.import_module(f"dashPages.{module_nm}.view") return rlt MENU_ITEMS = ['value_boxes', 'basic_cards', 'social_cards', 'tab_cards', 'basic_boxes'] for m in MENU_ITEMS: locals()[m] = load_module(m)
위와 같이 숫자로 된 파일은 에러를 뱉을 뿐 import 되지 않는다. 그럴 땐 아래와 같이 한다.
import importlib importlib.import_module('1234') p = importlib.import_module('1234') p.abc()
위와 같은 작업으로 import를 진행할 수 있다.
Class 명을 변수로 받아 동적으로 import (
python 의 모듈을 import 할때는 보통 파일 초기에 선언하여 사용하는게 일반적이다. 그런데, 모듈을 처음부터 import 하지 않고 로직에 따라 (모듈 명을 변수로 받아) 이것을 이용해 모듈을 import 하고 싶은 경우가 있다.
이런 경우 모듈과 class 명을 문자열로 받아 동적으로 import 하는 방법을 소개한다.
방법은 간단하다. importlib 패키지를 사용하거나 __import__() 함수를 이용하면 된다.
사실 importlib와 __import__() 함수는 큰 차이가 없다. importlib는 import 구문(statement)을 수행하는 package 일 뿐이며, __import__() 함수는 import 구문을 구성하는 expression 이기 때문이다. 즉, __import__() 함수는 importlib 보다 low level로 호출하는 것 뿐이다.
importlib
import 하고 싶은 module명을 module_name 이라는 변수로 받았다고 하자.
이런 경우 importlib를 이용해 아래 처럼 간단히 이용할 수 있다.
import importlib
def load_module_func(module_name):
mod = importlib.import_module(module_name)
return mod
mod 란 변수을 통해 module 안에 class를 호출이 가능하다.
import importlib importlib.import_module(name, package=None)
import_module() 함수는 importlib.__import__() 주위를 감싸는 단순화 래퍼 역할
import_module()이 지정된 패키지나 모듈(예를 들어 pkg.mod)을 반환
__import__()는 최상위 패키지나 모듈(예를 들어 pkg)을 반환
importlib.reload()
이미 한번 import된 모듈을 수정한 경우, 다시 import하고 싶을때, (커널 재식작없이)
import xxx
importlib.reload(xxx)
해당 모듈을 이미 참조하고 있던 다른 네임스페이스에서까지 적용되지 않아서, 사용에 제한이 있긴 하다.
__import__()
importlib 보다 좀 더 low level 로 __import__ 를 이용해서도 구현이 가능하다. 물론 이걸 사용하면, importlib 패키지 자체를 import 하는 과정은 생략해도 된다. __import__() 는 built-in 함수이기 때문에 그냥 사용하면 된다.
def load_module_func(module_name):
mod = __import__(‘%s’ %(module_name), fromlist=[module_name])
return mod
그럼 import 된 module 내부의 class 도 변수명으로 접근이 가능할까?
getattr() 이라는 함수를 이용하면 class 또한 변수명으로 접근이 가능하다.
__import__(name, globals=None, locals=None, fromlist=(), level=0)
getattr()
getattr() 은 지정한 object의 속성을 문자열 형태로 접근이 가능하도록 하는 함수이다. 이것을 이용하면 모듈의 class에 변수를 이용하여 접근이 가능하다. built-in 함수이기 때문에 특별히 참조할 필요는 없고 그냥 사용하면 된다.
def load_module_func(module_name, class_name):
mod = __import__(‘%s’ %(module_name), fromlist=[module_name])
cls = getattr(mod, class_name)(class_args)
cls.func1()
cls.func2(arg1, arg2)
…
참고