[python] 동적으로 가져온 모듈의 클래스 문자열 이름에서 동적 인스턴스화?

파이썬에서는 문자열에서 이름을 알고 특정 클래스를 인스턴스화해야하지만이 클래스는 동적으로 가져온 모듈에 ‘살아 있습니다’. 예는 다음과 같습니다.

로더 클래스 스크립트 :

import sys
class loader:
  def __init__(self, module_name, class_name): # both args are strings
    try:
      __import__(module_name)
      modul = sys.modules[module_name]
      instance = modul.class_name() # obviously this doesn't works, here is my main problem!
    except ImportError:
       # manage import error

동적으로로드 된 모듈 스크립트 :

class myName:
  # etc...

이 배열을 사용하여 dyn-loaded-modules에서 미리 정의 된 특정 동작에 따라 로더 클래스가 동적으로로드 된 모듈을 사용하도록합니다 …



답변

getattr 을 사용할 수 있습니다

getattr(module, class_name)

수업에 액세스합니다. 더 완전한 코드 :

module = __import__(module_name)
class_ = getattr(module, class_name)
instance = class_()

아래 에서 언급했듯이 importlib를 사용할 수 있습니다

import importlib
module = importlib.import_module(module_name)
class_ = getattr(module, class_name)
instance = class_()


답변

tl; dr

함수를 importlib.import_module사용하여 루트 모듈을 가져 와서 이름으로 클래스를로드하십시오 getattr.

# Standard import
import importlib
# Load "module.submodule.MyClass"
MyClass = getattr(importlib.import_module("module.submodule"), "MyClass")
# Instantiate the class (pass arguments to the constructor, if needed)
instance = MyClass()

설명

__import__하위 모듈을 가져올 수 없으므로 모듈을 이름으로 동적으로 가져 오는 데 사용하고 싶지 않을 것입니다 .

>>> mod = __import__("os.path")
>>> mod.join
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'join'

파이썬 문서가 말한 내용은 다음과 같습니다__import__ .

참고 : 이것은 importlib.import_module ()과 달리 일상적인 Python 프로그래밍에 필요하지 않은 고급 기능입니다.

대신 표준 importlib모듈을 사용하여 이름별로 모듈을 동적으로 가져 오십시오. 함께 getattr사용하면 다음 이름으로 클래스를 인스턴스화 할 수 있습니다 :

import importlib
my_module = importlib.import_module("module.submodule")
MyClass = getattr(my_module, "MyClass")
instance = MyClass()

당신은 또한 쓸 수 있습니다 :

import importlib
module_name, class_name = "module.submodule.MyClass".rsplit(".", 1)
MyClass = getattr(importlib.import_module(module_name), class_name)
instance = MyClass()

이 코드는 Python ≥ 2.7 (파이썬 3 포함)에서 유효합니다.


답변

getattr문자열의 이름에서 속성을 얻는 데 사용 합니다. 즉, 인스턴스를 다음과 같이 가져옵니다.

instance = getattr(modul, class_name)()


답변

복사하여 붙여 넣기 스 니펫 :

import importlib
def str_to_class(module_name, class_name):
    """Return a class instance from a string reference"""
    try:
        module_ = importlib.import_module(module_name)
        try:
            class_ = getattr(module_, class_name)()
        except AttributeError:
            logging.error('Class does not exist')
    except ImportError:
        logging.error('Module does not exist')
    return class_ or None


답변

이 문장 from foo.bar import foo2을 동적으로로드하려면이 작업을 수행해야합니다

foo = __import__("foo")
bar = getattr(foo,"bar")
foo2 = getattr(bar,"foo2")

instance = foo2()


답변

간단히 pydoc.locate함수 를 사용할 수 있습니다 .

from pydoc import locate
my_class = locate("module.submodule.myclass")
instance = my_class()


답변

위의 예제에서 유스 케이스에 도달하지 못했지만 Ahmad가 가장 가깝습니다 (감사합니다). 앞으로 이것을 읽는 사람들을 위해, 여기 나를 위해 일한 코드가 있습니다.

def get_class(fully_qualified_path, module_name, class_name, *instantiation):
    """
    Returns an instantiated class for the given string descriptors
    :param fully_qualified_path: The path to the module eg("Utilities.Printer")
    :param module_name: The module name eg("Printer")
    :param class_name: The class name eg("ScreenPrinter")
    :param instantiation: Any fields required to instantiate the class
    :return: An instance of the class
    """
    p = __import__(fully_qualified_path)
    m = getattr(p, module_name)
    c = getattr(m, class_name)
    instance = c(*instantiation)
    return instance