Python 클래스를 동적으로 로드하는 방법
예: Python 클래스:my_package.my_module.MyClass
딩하는가 은은?? 법??? ????
, 나는 그에 을 찾고 .Class.forName()
자바 파이썬구글 앱 엔진에서 작동해야 합니다.
바람직한 것은 클래스의 FQN을 문자열로 받아들여 클래스에 대한 참조를 반환하는 함수입니다.
my_class = load_class('my_package.my_module.MyClass')
my_instance = my_class()
python 문서에서 원하는 기능은 다음과 같습니다.
def my_import(name):
components = name.split('.')
mod = __import__(components[0])
for comp in components[1:]:
mod = getattr(mod, comp)
return mod
한 __import__
패키지 문자열의 첫 번째 도트 이후의 Import는 Import할 모듈의 속성이기 때문입니다.따라서 다음과 같은 기능은 작동하지 않습니다.
__import__('foo.bar.baz.qux')
위의 함수를 다음과 같이 호출해야 합니다.
my_import('foo.bar.baz.qux')
또는 이 예제의 경우:
klass = my_import('my_package.my_module.my_class')
some_object = klass()
편집: 나는 이것에 대해 약간 잘못 생각했다.기본적으로 원하는 것은 다음과 같습니다.
from my_package.my_module import my_class
위의 기능은 from 목록이 비어 있는 경우에만 필요합니다.따라서 적절한 콜은 다음과 같습니다.
mod = __import__('my_package.my_module', fromlist=['my_class'])
klass = getattr(mod, 'my_class')
'굴리다'에서 사용할 수 있는 .pydoc
다음과 같이 합니다.
from pydoc import locate
my_class = locate('my_package.my_module.MyClass')
은 여기에 있는 보다 더 좋다는 입니다.locate
는 모듈 내의 직접 오브젝트뿐만 아니라 제공된 닷 패스에서 python 오브젝트를 찾습니다.my_package.my_module.MyClass.attr
.
그 레시피가 궁금하다면, 그 기능은 다음과 같습니다.
def locate(path, forceload=0):
"""Locate an object by name or dotted path, importing as necessary."""
parts = [part for part in split(path, '.') if part]
module, n = None, 0
while n < len(parts):
nextmodule = safeimport(join(parts[:n+1], '.'), forceload)
if nextmodule: module, n = nextmodule, n + 1
else: break
if module:
object = module
else:
object = __builtin__
for part in parts[n:]:
try:
object = getattr(object, part)
except AttributeError:
return None
return object
에에 on on on on on 합니다.pydoc.safeimport
여기그 .
"""Import a module; handle errors; return None if the module isn't found.
If the module *is* found but an exception occurs, it's wrapped in an
ErrorDuringImport exception and reraised. Unlike __import__, if a
package path is specified, the module at the end of the path is returned,
not the package at the beginning. If the optional 'forceload' argument
is 1, we reload the module from disk (unless it's a dynamic extension)."""
import importlib
module = importlib.import_module('my_package.my_module')
my_class = getattr(module, 'MyClass')
my_instance = my_class()
Django를 사용하는 경우 를 사용할 수 있습니다.
네, OP가 장고를 요구한 것은 아니지만, 저는 장고 해결책을 찾다가 우연히 이 질문을 발견했고, 찾지 못했고, 그것을 찾는 다음 소년/갈을 위해 이 질문을 여기에 두었습니다.
# It's available for v1.7+
# https://github.com/django/django/blob/stable/1.7.x/django/utils/module_loading.py
from django.utils.module_loading import import_string
Klass = import_string('path.to.module.Klass')
func = import_string('path.to.module.func')
var = import_string('path.to.module.var')
Import가 하는 는 Import를 해 ..
,맘에 들다re
★★★★★★★★★★★★★★★★★」argparse
라이선스:
re = __import__('re')
def import_class(cl):
d = cl.rfind(".")
classname = cl[d+1:len(cl)]
m = __import__(cl[0:d], globals(), locals(), [classname])
return getattr(m, classname)
여기 제가 발견한 것을 공유하기 위해__import__
★★★★★★★★★★★★★★★★★」importlib
이 문제를 해결하려고 노력하면서요.
Python 3.7.3을 사용하고 있습니다.
에 d
''에서a.b.c
,
mod = __import__('a.b.c')
mod
네임스페이스 입니다.a
.
d
, ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★」
mod = getattr(mod, 'b') #mod is now module b
mod = getattr(mod, 'c') #mod is now module c
mod = getattr(mod, 'd') #mod is now class d
우리가 하려고 하면
mod = __import__('a.b.c')
d = getattr(mod, 'd')
요.a.d
.
「」를 사용하고 importlib
인 것을 것 getattr
'우리'를 쓸 importlib.import_module
가장 깊은 모듈의 핸들을 실제로 잡았습니다.
mod = importlib.import_module('a.b.c') #mod is module c
d = getattr(mod, 'd') #this is a.b.c.d
네, 저는 Python 2.7을 사용하고 있습니다.
a = __import__('file_to_import', globals(), locals(), ['*'], -1)
b = a.MyClass()
그러면 b는 클래스 'MyClass'의 인스턴스입니다.
원하는 클래스의 인스턴스가 이미 있는 경우 'type' 함수를 사용하여 클래스 유형을 추출하고 이를 사용하여 새 인스턴스를 생성할 수 있습니다.
class Something(object):
def __init__(self, name):
self.name = name
def display(self):
print(self.name)
one = Something("one")
one.display()
cls = type(one)
two = cls("two")
two.display()
Python에는 작업을 완료하기 위한 라이브러리 importlib가 내장되어 있습니다. : :: 패키지 이름을 파라미터로 동적으로 바이패스하는 모듈 메서드 및 클래스 메서드에 액세스하는 방법.다음은 예를 제시하겠습니다.
모듈 1:
def get_scenario_data():
return "module1 scenario data"
class Module1:
def module1_function1(self):
return "module1_function"
def module1_function2(self):
return "module2_function"
모듈 2:
def get_scenario_data():
return "module2 scenario data"
class Module2:
def module2_function1(self):
return "module2_function1"
def module2_function2(self):
return "module2_function2"
모듈 테스트:
- 패키지 이름에 따라 모듈 메서드에 param으로 동적으로 액세스합니다.
- 패키지 이름을 기반으로 클래스 메서드에 param으로 동적으로 액세스합니다.
모듈 테스트
import importlib
module = importlib.import_module('pack1.nestedpack1.module1')
print(module.get_scenario_data())
modul1_cls_obj = getattr(module, 'Module1')()
print(modul1_cls_obj.module1_function1())
print(modul1_cls_obj.module1_function2())
module = importlib.import_module('pack1.nestedpack1.module2')
modul2_cls_obj = getattr(module, 'Module2')()
print(modul2_cls_obj.module2_function1())
print(modul2_cls_obj.module2_function2())
print(module.get_scenario_data())
결과.
module1 scenario data
module1_function
module2_function
module2_function1
module2_function2
module2 scenario data
PyPI 모듈 오토로더 및 Import
# PyPI imports
import pkg_resources, subprocess, sys
modules = {'lxml.etree', 'pandas', 'screeninfo'}
required = {m.split('.')[0] for m in modules}
installed = {pkg.key for pkg in pkg_resources.working_set}
missing = required - installed
if missing:
subprocess.check_call([sys.executable, '-m', 'pip', 'install', '--upgrade', 'pip'])
subprocess.check_call([sys.executable, '-m', 'pip', 'install', *missing])
for module in set.union(required, modules):
globals()[module] = __import__(module)
테스트:
print(pandas.__version__)
print(lxml.etree.LXML_VERSION)
기존 답변에 약간의 정교함을 더하고 있습니다.
사용 예에 따라서는, 풀 패스를 명시적으로 지정할 필요가 있어 불편할 수 있습니다(예:package.subpackage.module...
Import할 클래스/클래스)를 지정합니다.importlib 외에도__init__.py
더 깨끗하게 하려고요
예를 들어 다음과 같은 python 패키지가 있다고 합시다.
├── modes
│ ├── __init__.py
│ ├── bar.py
│ ├── foo.py
│ ├── modes.py
foo.py
예를 들어, 프로그램의 다른 곳에서 사용하고 싶은 수업/수업을 들 수 있습니다.
from modes.modes import Mode
class Foo(Mode):
def __init__(self, *arg, **kwargs):
super(Foo, self).__init__(*arg, **kwargs)
def run(self):
self.LOG.info(f"This is FOO!")
명령줄 인수를 사용하면 실행하는 모드에 대응하는 인수를 전달할 수 있습니다.저는 다음과 같이 하고 싶습니다.
def set_mode(mode):
""" """
import importlib
module = importlib.import_module('modes.foo')
getattr(module, mode)().run()
출력:
>> set_mode("Foo")
>> engine_logger:INFO - This is FOO!
이 방법은 잘 작동하지만, 우리가 정말로 원하는 것은 다음과 같습니다.
def set_mode(mode):
""" """
import importlib
module = importlib.import_module('modes') # only import the package, not modules explicitely
getattr(module, mode)().run()
이로 인해 다음 오류가 발생합니다.
>> set_mode("Foo")
>> AttributeError: module 'modes' has no attribute 'Foo'
단, 다음 항목을 추가할 수 있습니다./modes/__init__.py
:
from .foo import Foo
from .bar import Bar
다음 작업을 수행할 수 있습니다.
>> set_mode("Foo")
>> engine_logger:INFO - This is FOO!
>> set_mode("Bar")
>> engine_logger:INFO - This is BAR!
다른 세계에서는 init.py에서 Import하는 모든 서브모듈/submodule/submodule/submodule/submodule은 importlib.import_submodule(...)을 사용하여 외부에서 전체 경로를 지정할 필요가 없습니다.
Google App Engine에는webapp2
호출된 함수import_string
자세한 내용은 이쪽을 참조해 주세요.https://webapp-improved.appspot.com/api/webapp2.html
그렇게,
import webapp2
my_class = webapp2.import_string('my_package.my_module.MyClass')
예를 들어, 이것은webapp2.Route
핸들러 또는 문자열을 사용할 수 있습니다.
module = __import__("my_package/my_module")
the_class = getattr(module, "MyClass")
obj = the_class()
언급URL : https://stackoverflow.com/questions/547829/how-to-dynamically-load-a-python-class
'source' 카테고리의 다른 글
AWS RDS 읽기 복제품:몇 개의 테이블과 열의 복제를 방지하려면 어떻게 해야 합니까? (0) | 2022.10.29 |
---|---|
MariaDB에서 Mysql로 마이그레이션 - 중복 제약 조건 이름 (0) | 2022.10.29 |
팬더 인덱스 컬럼 제목 또는 이름 (0) | 2022.10.20 |
mysql/mariadb(또는 amazon orora)에서의 멀티 테넌트(Multi-tenant) 접근방식의 실용적인 구현 (0) | 2022.10.20 |
Class 파일의 바이트 코드를 볼 수 있나요? (0) | 2022.10.20 |