Python : 하위 패키지 또는 하위 모듈 가져 오기
이미 플랫 패키지를 사용하고 있었기 때문에 중첩 패키지에서 발생한 문제를 예상하지 못했습니다. 여기 ...
디렉토리 레이아웃
dir
|
+-- test.py
|
+-- package
|
+-- __init__.py
|
+-- subpackage
|
+-- __init__.py
|
+-- module.py
init .py의 내용
모두 package/__init__.py
와 package/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
'IT TIP' 카테고리의 다른 글
WordPress 단축 코드에서 AJAX를 사용하는 방법? (0) | 2020.11.05 |
---|---|
[사실] 속성은 무엇입니까? (0) | 2020.11.05 |
Xcode 6은 각 실행 후 iOS8 시뮬레이터에서 내 앱의 디렉토리 이름을 계속 변경합니다. (0) | 2020.11.05 |
PHP는 클래스 이름에서 객체를 문자열로 인스턴스화 할 수 있습니까? (0) | 2020.11.04 |
컴파일러가 "missing initializer"라는 경고를 던지는 이유는 무엇입니까? (0) | 2020.11.04 |