동적으로 Import된 모듈의 클래스 문자열 이름에서 동적 인스턴스화?
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
some-dynamically-loaded-interval 스크립트:
class myName:
# etc...
이 배열을 사용하여 동적으로 로드된 모듈을 로더 클래스에서 사용할 수 있도록 합니다. dyn-loaded-modules의 사전 정의된 동작에 따라...
getatr을 사용할 수 있습니다.
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_()
dr;dr
루트 모듈을 Import 합니다.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__
서브모듈을 Import할 수 없으므로 모듈 이름을 사용하여 동적으로 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'
다음은 python doc가 말하는 것입니다.__import__
:
주의: 이것은 importlib.import_module()과 달리 일상적인 Python 프로그래밍에서는 필요하지 않은 고급 함수입니다.
대신 표준 모듈을 사용하여 모듈을 이름으로 동적으로 Import합니다.그러면 이름을 사용하여 클래스를 인스턴스화할 수 있습니다.
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 2.7(python 3 포함)에서 유효합니다.
복사 붙여넣기 스니펫:
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
사용하다getattr
문자열 이름에서 속성을 가져옵니다.즉, 인스턴스를 다음과 같이 가져옵니다.
instance = getattr(modul, class_name)()
를 간단하게 사용할 수 있습니다.pydoc.locate
기능.
from pydoc import locate
my_class = locate("module.submodule.myclass")
instance = my_class()
이 문장을 원한다면from foo.bar import foo2
동적으로 로드하려면 이 작업을 수행해야 합니다.
foo = __import__("foo")
bar = getattr(foo,"bar")
foo2 = getattr(bar,"foo2")
instance = foo2()
문자열에서 클래스 및 메서드를 Import하려면 다음 작업을 수행해야 합니다.
dynamic_import
│ my_class.py
│
└───subfolder
│ │ my_subfolder_module.py
│ │
my_sysloger_syslogs.화이
class MySubfolderClass():
def test_method(self):
print ("Hello World")
main.py
import importlib
module = importlib.import_module('subfolder.my_subfolder_module')
class_ = getattr(module, "MySubfolderClass")
method_instance = getattr(class_(),"test_method")
method_instance()
#it will output the result of the test method, which is "Hello World"
위의 예로는 제 사용 사례에 거의 도달할 수 없었습니다만, 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
다음 코드 조각 사용:
def to_class(path:str):
try:
from pydoc import locate
class_instance = locate(path)
except ImportError:
print('Module does not exist')
return class_instance or None
사용방법:
당신의 클래스 이름이 인 경우MyClass
에 배치되어 있습니다.my_app.models.MyClass
그 후, 다음과 같이 합니다.
path = "my_app.models.MyClass"
my_class = to_class(path)
언급URL : https://stackoverflow.com/questions/4821104/dynamic-instantiation-from-string-name-of-a-class-in-dynamically-imported-module
'source' 카테고리의 다른 글
오브젝트 URL에서 파일 또는 BLOB를 가져오려면 어떻게 해야 합니까? (0) | 2023.01.12 |
---|---|
암호화 없이 PHP 코드를 보호하는 최적의 솔루션 (0) | 2023.01.12 |
JavaScript 오류(Uncatched SyntaxError:예기치 않은 입력 종료) (0) | 2023.01.12 |
nodejs 도킹된 앱이 mariadb 도킹된 데이터베이스에 연결할 수 없습니다. (0) | 2023.01.12 |
Google 자동 완성 결과를 시/군만으로 제한하는 방법 (0) | 2023.01.12 |