2012-07-16 4 views
1

내 프로젝트에서 내부 가져 오기를 사용하는 데 어려움이 있습니다. logger.pyconfig.py 모듈은 모든 패키지의 모듈에 필요한하위 패키지에서 공유 모듈에 액세스

app 
    |- Gui.py 
    |- Main.py 
    |- logger.py 
    |- config.py 
    |- WebParser (package) 
     |- __init__.py 
     |- LinksGrabber.py 
     |- LyricsGrabber.py 
     |- ImagesGrabber.py 
    |- (Many other packages...) 

및 (사용하는 경우에만 bulit-모듈) 독립적이 내 프로젝트의 부분적인 트리 구조입니다. 패키지 내부에서 이러한 모듈에 액세스하는 것은 까다로운 작업입니다.

이 내가 구성 액세스를 활성화하고 WebParser\LinksGrabber.py에 기능을 로그인하는, 그것을 달성하기 위해 시도하는 방법이다 :

# WebParser\__init__.py: 
sys.path.append('..') # for outside-package modules 
import config 
from logger import log 

# WebParser\LinksGrabber.py: 
import WebParser 
config = WebParser.config 
log = WebParser.log 

문제들 :이 코드 냄새가

  • . 이 동작을 수행하는 더 좋은 방법이있을 것입니다.
  • import WebParser으로 전화하고 암시 적으로 가져 오지 않고 WebParser.LinksGrabberWebParser.LyricsGrabber을 바로 사용하고 싶습니다. 이것은 __init__.py 안에 모듈을 가져 오기로 할 수 있지만 모든 패키지의 모듈이 패키지 자체를 가져 오기 때문에 가능하지 않으며 재귀 적 가져 오기를 실행합니다.

더 나은 구현이나 다른 코드 디자인을 제안 할 수 있습니까?

from .. import config 
from ..logger import log 
+0

"모든 모듈은 패키지 자체를 가져옵니다"라고 말하면 어떤 모듈입니까? 외부 디렉토리 (config, Gui 등)의 모든 모듈이 WebParser를 가져 오지만 WebParser의 모든 모듈도 외부 모듈을 가져오고 있다는 것을 의미합니까? 아니면 WebParser 내의 모듈이 WebParser 자체를 가져오고 있다는 것을 의미합니까? – BrenBarn

+0

WebParser 내부의 모든 모듈이 WebParser 자체를 가져옵니다. – iTayb

답변

1

당신은 그에게 __init__.py 파일을 제공하여 app 패키지를 확인해야합니다 :

+0

가 없습니다. LinksGrabber'와'ImportLinkGrabber'를 가져 오시겠습니까? 그리고'__init__'는 많은 서브 모듈에 필요한 함수를 구현하지 않아야합니까? 아마도 특정 폴더를 패키지로 정의하는 것 외에도'__init __. py' 파일의 목적을 이해하지 못했을 것입니다. – iTayb

+1

'__init__'은 패키지를 초기화하기로되어 있습니다. 자주 빈 파일입니다. 때로는 특정 하위 모듈을 가져 와서 사용자가 쉽게 액세스 할 수 있도록합니다. 그러나 "패키지 전체"공통 기능을위한 장소가 아닙니다. 그것들은 패키지 안에 별도의 모듈에 있어야합니다. 그 이유는 여러분이 발견 한 바로 그 것입니다 :'__init__'을 사용하여 공통 함수 *와 *를 사용하여 서브 모듈을 가져 오려고하면 서브 모듈에 공통 함수가 필요하므로 순환 가져 오기 문제가 있습니다. 공통 기능에서 초기화를 분리하십시오. – BrenBarn

+0

또한 'from. import importGrabber'와'import LinksGrabber'는 절대 import가 가능하지 않다면 (즉,'from __future__ import absolute_import'가 없다면) 파이썬 2에서 동일합니다. 절대 import가 가능하다면 (항상 파이썬 3에서와 같이),'import LinksGrabber'는 작동하지 않을 것입니다. 또한 'from. import LinksGrabber'는'import WebParser'와는 같지 않습니다. 이것은 당신이하고 있다고 말한 것입니다. – BrenBarn

0

당신이 여기 relative imports를 사용할 수있는 것으로 보인다. 파이썬 관련 가져 오기 시스템은 패키지 안에 만 작동합니다. 그런 다음 WebParser 모듈 내부에서 from .. import config, from .. import Gui 등을 수행 할 수 있습니다.

WebPackage를 내부 패키지에서 가져 오는 데는 코드 냄새가 있습니다. 왜 그럴 필요가 있니? 상대적인 가져 오기를 사용하면 예를 들어 ImagesGrabber 안에 from . import LinksGrabber 등을 넣어 필요한 것을 액세스 할 수 있습니다. 많은 하위 모듈에서 필요로하는 WebParser 패키지의 일부 기능이있는 경우 WebParser의 별도 모듈로 해당 기능을 가져와야합니다.

+0

외부'app' 디렉토리에'__init __. py'를 주면 패키지를 만들지 않으면 작동하지 않습니다. – BrenBarn

+0

@BrenBarn - 동의 함. 나는 그것이 단지 주어진 것이라고 생각한 것 같지만, 아마 나쁜 가정이다. 그리고 아마도'__init __. py '를 추가하는 것은 OP가 요구하는 "더 나은 구현"이다. – mgilson

1

외부 (app) 디렉토리 전체를 파이썬 패키지 (__ init__.py)로 만들 것입니다. 영구적으로 파이썬 경로에 '응용 프로그램'을 설치,

#!/usr/bin/env python 

from distutils.core import setup 

setup(name='app', 
     version='1.0', 
     description='My app', 
     author='Greg Ward', 
     packages=['app'], 
    ) 

다음 실행할 수 있습니다 python setup.py install :

app_files 
    |- ***setup.py*** 
    |- app 
    |- ***__init__.py*** 
    |- Gui.py 
    |- Main.py 
    |- logger.py 
    |- config.py 
    |- WebParser (package) 
      |- __init__.py 
      |- LinksGrabber.py 
      |- LyricsGrabber.py 
      |- ImagesGrabber.py 
    |- (Many other packages...) 

setup.py이 같은 간단한 일이 될 것입니다. 이것은 내 의견으로는 sys.path hacks를 사용하지 않고도 할 수있는 최선의 방법입니다.

그럼, 어디 파이썬에서 당신은 전체 점선 경로

import app.logger 
import app.config 
import app.WebParser 

바로 가져 오기 응용 프로그램에서 LinksGrabber 및 LyricsGrabber 사용할 수 있도록하는 유일한 방법에서 파일의 참조 할 수 있습니다. WebParser는 앱에서 가져 오는 것입니다.WebParser .__ init__.

+0

'app'는 패키지인지 여부에 대한 문제는'setup.py'를 사용하여 시스템 전체에 설치되었는지와 별개입니다. 많은 경우 (예를 들어, 개발할 때) 항상'setup.py '를 사용하여 설치하려고하지 않을 수도 있습니다. 그러나'__init __. py'를주고 패키지 디렉토리가 시스템 경로에 있는지 확인하면 작동 할 것입니다. – BrenBarn

+0

개발할 때 'python setup.py develop'을 사용하여 설치하는 디렉토리에 대한 심볼릭 링크로 (본질적으로) 시스템 경로에 설치하는 것이 좋습니다. 그렇게하면 변경 사항이 시스템에 즉시 전달됩니다. 브렌 반 (BrenBarn)이 말한 바대로, setup.py를 시스템 경로에 설치할 필요가 없지만 다른 모든 방법은 hackish를 느낄 것입니다. – jdeuce

+0

최상위 폴더를 'PYTHONPATH'에 영구적으로 추가하는 것이 올바른지 확실하지 않습니다. 문제는 "영구적으로"또는 "임시적으로"하는 것이 아니라 조금 덜 해킹 된 방법을 찾는 것입니다. 상대적인 수입은 더 좋은 생각처럼 보입니다. +1 좋은 접근 방식을, 그러나. – iTayb

관련 문제