Python의 __import__는 예상대로 작동하지 않습니다
-
03-07-2019 - |
문제
사용할 때 __import__
점으로 표시된 이름으로 다음과 같은 것입니다. somepackage.somemodule
, 리턴 된 모듈은 그렇지 않습니다 somemodule
, 반품이 무엇이든 대부분 비어있는 것 같습니다! 여기서 무슨 일이야?
해결책
파이썬 문서에서 __import__
:
__import__( name[, globals[, locals[, fromlist[, level]]]])
...
이름 변수가 form package.module의 경우 일반적으로 이름별로 명명 된 모듈이 아닌 최상위 패키지 (첫 번째 점까지의 이름 업)가 반환됩니다. 그러나리스트에서 비어 있지 않은 인수가 주어지면 이름별로 명명 된 모듈이 반환됩니다. 이것은 다른 종류의 가져 오기 명령문에 대해 생성 된 바이트 코드와의 호환성을 위해 수행됩니다. "Import Spam.ham.eggs"를 사용하는 경우, 최상위 패키지 스팸을 가져 오는 네임 스페이스에 배치해야하지만 "Spam.ham Import Eggs"를 사용할 때는 Spam.ham 하위 패키지를 사용하여 Eggs 변수를 찾는 데 사용해야합니다. . 이 동작의 해결 방법으로 getAttr ()를 사용하여 원하는 구성 요소를 추출하십시오. 예를 들어 다음 도우미를 정의 할 수 있습니다.
def my_import(name): mod = __import__(name) components = name.split('.') for comp in components[1:]: mod = getattr(mod, comp) return mod
역설 :
당신이 요청할 때 somepackage.somemodule
, __import__
보고 somepackage.__init__.py
, 종종 비어 있습니다.
돌아올 것입니다 somemodule
당신이 제공하는 경우 fromlist
(내부의 변수 이름 목록 somemodule
실제로 반환되지 않은 당신은 원합니다)
내가했던 것처럼 그들이 제안한 기능을 사용할 수도 있습니다.
참고 : 나는이 질문에 직접 대답하려는 의도를 완전히 물었다. 내 코드에는 큰 버그가 있었고, 그것을 잘못 진단 한 후, 그것을 알아내는 데 오랜 시간이 걸렸습니다. 그래서 나는 So 커뮤니티를 도와주고 내가 여기에있는 Gotcha를 게시 할 것이라고 생각했습니다.
다른 팁
Python 2.7에는 importlib, 점선 경로가 예상대로 해결되었습니다.
import importlib
foo = importlib.import_module('a.dotted.path')
instance = foo.SomeClass()
문서에 설명 된대로 더 간단한 솔루션이 있습니다.
단순히 이름으로 모듈 (패키지 내)을 가져 오려면 __import __ ()를 호출 한 다음 Sys.Modules에서 찾을 수 있습니다.
>>> import sys
>>> name = 'foo.bar.baz'
>>> __import__(name)
<module 'foo' from ...>
>>> baz = sys.modules[name]
>>> baz
<module 'foo.bar.baz' from ...>
원하는대로 작동하는 것이 있습니다. twisted.python.reflect.namedAny
:
>>> from twisted.python.reflect import namedAny
>>> namedAny("operator.eq")
<built-in function eq>
>>> namedAny("pysqlite2.dbapi2.connect")
<built-in function connect>
>>> namedAny("os")
<module 'os' from '/usr/lib/python2.5/os.pyc'>
Python 2.6의 경우이 스 니펫을 썼습니다.
def import_and_get_mod(str, parent_mod=None):
"""Attempts to import the supplied string as a module.
Returns the module that was imported."""
mods = str.split('.')
child_mod_str = '.'.join(mods[1:])
if parent_mod is None:
if len(mods) > 1:
#First time this function is called; import the module
#__import__() will only return the top level module
return import_and_get_mod(child_mod_str, __import__(str))
else:
return __import__(str)
else:
mod = getattr(parent_mod, mods[0])
if len(mods) > 1:
#We're not yet at the intended module; drill down
return import_and_get_mod(child_mod_str, mod)
else:
return mod
내가 한 방식은
foo = __import__('foo', globals(), locals(), ["bar"], -1)
foobar = eval("foo.bar")
그런 다음 BY의 컨텐츠에 액세스 할 수 있습니다
foobar.functionName()