2012-06-06 5 views
1

다음은 파이썬 모듈입니다. foosys.path입니다.하위 모듈의 클래스를 상위 모듈의 네임 스페이스에서 사용하려면 어떻게해야합니까?

foo\ 
    __init__.py 
    bar\ 
     __init__.py 
     base.py 
      class Base(object) 
     derived.py 
      import foo.bar.base as base 
      class Derived(base.Base) 

아직 멋진 일이 없습니다. 나는 derived 모듈에서 파생 클래스를 인스턴스화 할 경우에, 나는 충분히 쉽게 그렇게 할 수 있습니다

import foo.bar.derived as derived 
print(derived.Derived()) 

그러나, 나는 그냥 bar 모듈을 가져 bar.Derived()를 호출하고 싶습니다, 내가 가지고있는 계획 때문에 다른 많은 모듈 내에서 많은 클래스를 사용하고 있으며, 나는이 모든 tentacular import paths를 다루고 싶지 않습니다.

import foo.bar as bar 
print(bar.Derived()) 

: 나는 다음을 수행 할 수 있어야한다

이제
foo\ 
    __init__.py 
    bar\ 
     __init__.py 
      from foo.bar.derived import Derived 
     base.py 
      class Base(object) 
     derived.py 
      import foo.bar.base as base 
      class Derived(base.Base) 

: 나의 이해는 단순히, 그래서처럼 내 프로젝트를 수정하여 bar 모듈의 네임 스페이스에를 파생 가져올 수 있다는 것입니다 하지만 foo 모듈에 bar이라는 서브 모듈이 없다는 불평을하는 AttributeError가 발생했습니다.

test.py    (1): import foo.bar 
foo\bar\__init__.py (1): from foo.bar.derived import Derived 
foo\bar\derived.py (1): import foo.bar.base as base 

AttributeError: 'module' object has no attribute 'bar' 

사실, 원래의 테스트 코드 (위)가 작동하지 않습니다! foo.bar을 가져 오면 오류가 발생합니다. 나는이 오류에서 빛나고 수있는 일

는 자신의 기본 클래스를 포함하는 __init__.py에서 import 문이 bar 전에 실행해야 할 derived.py가 완전히로드가 발생, 따라서 그것 (bar에서도) 모듈을 가져올 수 있다는 것입니다. 울트라 중첩 네임 스페이스가 필수적이지 않고 간단한 전방 선언이이 문제를 부정하는 C++ 세계에서 온 것입니다.하지만 필자가 찾고있는 것이 가능하고 적어도 다소 수용 가능한 Pythonic 솔루션. 내가 도대체 ​​뭘 잘못하고있는 겁니까? 부모 모듈의 네임 스페이스에서 하위 모듈의 클래스를 사용할 수있는 올바른 방법은 무엇입니까?

답변

5

파이썬 2.5 이상에서 작업하는 경우, 명시 적으로 상대의 수입을 사용하여 (http://www.python.org/dev/peps/pep-0328/#guido-s-decision를) 시도 : 당신이 실제로 파이썬 2.5 또는 2.6로 작업하는 경우

test.py    (1): import foo.bar 
foo\bar\__init__.py (1): from .derived import Derived 
foo\bar\derived.py (1): from . import base 

(당신이해야하는 것으로 . 당신의 모듈에 from __future__ import absolute_import 포함)

1

derived.py에서, 이것을 사용 :

편집을 : JAB가 지적했듯이, 암시 상대 수입은 deprecat 있습니다 ed은 다음과 같이 권장되지 않습니다 (하지만 여전히 Python 2.7에서 작동합니다 - 더 이상 사용하지 않는 오류가 없습니다!).

수입 기본 #이 당신이 필요로하는 모든 - 그것은,

대신 현재 디렉토리에서의 사용 :

from . import base # 

(또는)

from foo.bar import base 

대신 :

import foo.bar.base as base 

동일한 문제로 인해 두 오류가 모두 해결됩니다. foo.bar.base 모듈 내에 base 함수 또는 클래스가 없으므로 가져 오기가 작동하지 않습니다.

+0

암시 적으로 상대적인 가져 오기는 현재 시점에서 더 이상 사용되지 않으므로, 꼭 사용해야하는 경우가 아니라면 사용하지 않는 것이 좋습니다 (예 : 2.5보다 오래된 Python 버전으로 작업하는 경우). – JAB

+0

@JAB :'base'는'derived'와 같은 디렉토리에 있습니다. 당신은'import base' (같은 디렉토리에 모듈을 임포트)가 ** 더 이상 사용되지 않을 것이라고 말하고 있습니까? ** ?? – Gerrat

+0

"파이썬 2.6에서 인트라 패키지 가져 오기를 수행하는'import' 문은'DeprecationWarning'을 발생시킵니다 (이것은 상대 import 구문을 사용하지 못하는'from <> import'에도 적용됩니다)." 필자는이 컴퓨터에 Python 2.6 복사본을 설치하지 않았으므로 테스트 할 수 있지만 그렇게 할 것이라고 확신합니다. 또한, http://www.python.org/dev/peps/pep-0328/#rationale-for-absolute-imports – JAB

관련 문제