development

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

big-blog 2020. 6. 9. 07:46
반응형

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


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

로더 클래스 스크립트 :

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()

I couldn't quite get there in my use case from the examples above, but Ahmad got me the closest (thank you). For those reading this in the future, here is the code that worked for me.

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

One can simply use the pydoc.locate function.

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

참고URL : https://stackoverflow.com/questions/4821104/dynamic-instantiation-from-string-name-of-a-class-in-dynamically-imported-module

반응형