IT TIP

Python : 하위 패키지 또는 하위 모듈 가져 오기

itqueen 2020. 11. 5. 19:57
반응형

Python : 하위 패키지 또는 하위 모듈 가져 오기


이미 플랫 패키지를 사용하고 있었기 때문에 중첩 패키지에서 발생한 문제를 예상하지 못했습니다. 여기 ...

디렉토리 레이아웃

dir
 |
 +-- test.py
 |
 +-- package
      |
      +-- __init__.py
      |
      +-- subpackage
           |
           +-- __init__.py
           |
           +-- module.py

init .py의 내용

모두 package/__init__.pypackage/subpackage/__init__.py비어 있습니다.

의 내용 module.py

# file `package/subpackage/module.py`
attribute1 = "value 1"
attribute2 = "value 2"
attribute3 = "value 3"
# and as many more as you want...

내용 test.py(3 개 버전)

버전 1

# file test.py
from package.subpackage.module import *
print attribute1 # OK

그것은 물건을 가져 오는 (대량으로 모두 가져 오기)의 나쁘고 안전하지 않은 방법이지만 작동합니다.

버전 2

# file test.py
import package.subpackage.module
from package.subpackage import module # Alternative
from module import attribute1

더 안전한 방법으로 항목별로 가져 오지만 실패합니다. Python은 이것을 원하지 않습니다. "No module named module"메시지와 함께 실패합니다. 그러나…

# file test.py
import package.subpackage.module
from package.subpackage import module # Alternative
print module # Surprise here

… 말한다 <module 'package.subpackage.module' from '...'>. 그래서 그것은 모듈이지만 그것은 모듈이 아닙니다 / -P 8-O ... 어

버전 3

# file test.py v3
from package.subpackage.module import attribute1
print attribute1 # OK

이것은 작동합니다. 그래서 당신은 항상 overkill 접두사를 사용하거나 버전 # 1에서와 같이 안전하지 않은 방법을 사용하고 Python에서 안전하고 편리한 방법을 사용하는 것을 허용하지 않습니까? 안전하고 불필요한 긴 접두사를 피하는 더 좋은 방법은 Python이 거부하는 유일한 방법입니까? 그것을 사랑하기 때문이다 import *하거나 (이 연습을 시행하는 데 도움이되지 않습니다) 너무 긴 접두사를 사랑하기 때문에?

어려운 말로 미안하지만이 멍청한 행동을 해결하려고 노력하는 이틀입니다. 내가 어딘가에서 완전히 틀린 것이 아니라면, 파이썬의 패키지 및 하위 패키지 모델에서 무언가가 정말로 망가 졌다는 느낌이들 것입니다.

메모

  • 나는 sys.path글로벌 부작용을 피하기 위해, 또는 동일한 글로벌 효과 *.pth를 가지고 놀 수있는 또 다른 방법 인 파일 에 의존하고 싶지 않습니다 sys.path. 솔루션이 깨끗하려면 로컬에만 있어야합니다. Python은 하위 패키지를 처리 ​​할 수 ​​있지만 그렇지 않은 경우에도 로컬 항목을 처리 할 수 ​​있도록 전역 구성을 사용할 필요가 없습니다.
  • 나는 또한에서 가져 오기를 사용해 보았지만 package/subpackage/__init__.py아무것도 해결하지 subpackage못했고 똑같이 수행 하며 알려진 모듈이 아니라고 불평 print subpackage하고 모듈이라고 말합니다 (이상한 동작).

내가 완전히 틀렸을 수도 있지만 (내가 선호하는 옵션) 파이썬에 대해 많이 실망하게 만듭니다.

내가 시도한 세 가지 외에 다른 알려진 방법이 있습니까? 내가 모르는 것?

(한숨)

----- % <----- 편집 -----> % -----

지금까지의 결론 (사람들의 의견 후)

모든 패키지 참조가 전역 사전으로 이동하기 때문에 Python의 실제 하위 패키지와 같은 것은 없습니다. 즉, 로컬 패키지 참조를 관리 할 방법이 없음을 의미하는 로컬 사전이 없음을 의미합니다.

전체 접두사 또는 짧은 접두사 또는 별칭을 사용해야합니다. 에서와 같이 :

전체 접두사 버전

from package.subpackage.module import attribute1
# An repeat it again an again
# But after that, you can simply:
use_of (attribute1)

짧은 접두사 버전 (반복 접두사)

from package.subpackage import module
# Short but then you have to do:
use_of (module.attribute1)
# and repeat the prefix at every use place

또는 위의 변형입니다.

from package.subpackage import module as m
use_of (m.attribute1)
# `m` is a shorter prefix, but you could as well
# define a more meaningful name after the context

분해 된 버전

한 번에 여러 항목을 일괄 적으로 가져 오는 것이 마음에 들지 않으면 다음을 수행 할 수 있습니다.

from package.subpackage.module import attribute1, attribute2
# and etc.

내가 가장 좋아하는 취향은 아니지만 (수입 된 법인 당 하나의 수입 명세서를 선호 함) 개인적으로 선호 할 수 있습니다.

업데이트 (2012-09-14) :

마침내 레이아웃에 대한 주석을 제외하고는 실제로 괜찮은 것처럼 보입니다. 위의 대신 다음을 사용했습니다.

from package.subpackage.module import (

    attribute1, 
    attribute2,
    attribute3,
    ...)  # and etc.

You seem to be misunderstanding how import searches for modules. When you use an import statement it always searches the actual module path (and/or sys.modules); it doesn't make use of module objects in the local namespace that exist because of previous imports. When you do:

import package.subpackage.module
from package.subpackage import module
from module import attribute1

The second line looks for a package called package.subpackage and imports module from that package. This line has no effect on the third line. The third line just looks for a module called module and doesn't find one. It doesn't "re-use" the object called module that you got from the line above.

In other words from someModule import ... doesn't mean "from the module called someModule that I imported earlier..." it means "from the module named someModule that you find on sys.path...". There is no way to "incrementally" build up a module's path by importing the packages that lead to it. You always have to refer to the entire module name when importing.

It's not clear what you're trying to achieve. If you only want to import the particular object attribute1, just do from package.subpackage.module import attribute1 and be done with it. You need never worry about the long package.subpackage.module once you've imported the name you want from it.

If you do want to have access to the module to access other names later, then you can do from package.subpackage import module and, as you've seen you can then do module.attribute1 and so on as much as you like.

If you want both --- that is, if you want attribute1 directly accessible and you want module accessible, just do both of the above:

from package.subpackage import module
from package.subpackage.module import attribute1
attribute1 # works
module.someOtherAttribute # also works

If you don't like typing package.subpackage even twice, you can just manually create a local reference to attribute1:

from package.subpackage import module
attribute1 = module.attribute1
attribute1 # works
module.someOtherAttribute #also works

The reason #2 fails is because sys.modules['module'] does not exist (the import routine has its own scope, and cannot see the module local name), and there's no module module or package on-disk. Note that you can separate multiple imported names by commas.

from package.subpackage.module import attribute1, attribute2, attribute3

Also:

from package.subpackage import module
print module.attribute1

If all you're trying to do is to get attribute1 in your global namespace, version 3 seems just fine. Why is it overkill prefix ?

In version 2, instead of

from module import attribute1

you can do

attribute1 = module.attribute1

참고URL : https://stackoverflow.com/questions/12229580/python-importing-a-sub-package-or-sub-module

반응형