예를 들어 파이썬 클래스의 문자열이 주어진다면 my_package.my_module.MyClass
그것을로드하는 가장 좋은 방법은 무엇입니까?
즉 Class.forName()
, Java에서 동등한 기능을 찾고 있는데 Python에서는 기능입니다. Google App Engine에서 작동해야합니다.
바람직하게 이것은 클래스의 FQN을 문자열로 받아들이고 클래스에 대한 참조를 반환하는 함수입니다.
my_class = load_class('my_package.my_module.MyClass')
my_instance = my_class()
답변
파이썬 문서에서 원하는 기능은 다음과 같습니다.
def my_import(name):
components = name.split('.')
mod = __import__(components[0])
for comp in components[1:]:
mod = getattr(mod, comp)
return mod
단순 __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
위의 기능은 비어있는 fromlist 가있는 경우에만 필요합니다 . 따라서 적절한 호출은 다음과 같습니다.
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
찾을 수 있는 직접 모듈 내에서 제공된 점으로 구분 된 경로에서 파이썬 객체뿐만 아니라 객체를. 예 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
그것은 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()
답변
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)
답변
Django를 사용하는 경우 이것을 사용할 수 있습니다. 예, OP가 django를 요청하지 않았다는 것을 알고 있지만 Django 솔루션을 찾고이 질문을 찾지 못했습니다.
# 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')
당신이없는 것을 가져 오려면, 명심 .
처럼, re
또는 argparse
사용을 :
re = __import__('re')
답변
저는 여기에서 찾을 것을 공유하는 것입니다 __import__
및 importlib
이 문제를 해결하기 위해 노력하면서.
Python 3.7.3을 사용하고 있습니다.
I 클래스에 도달 할 때 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’클래스의 인스턴스입니다.
