由于已经使用了平面软件包,我没有预料到在使用嵌套软件包时会遇到这样的问题。
dir
|
+-- test.py
|
+-- package
|
+-- __init__.py
|
+-- subpackage
|
+-- __init__.py
|
+-- module.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 versions)# file test.py
from package.subpackage.module import *
print attribute1 # OK
That's the bad and unsafe way of importing things (import all in a bulk), but it works.
# file test.py
import package.subpackage.module
from package.subpackage import module # Alternative
from module import attribute1
一种更安全的导入方法,逐项导入,但是它失败了,Python 不希望这样: 失败的消息是: “没有命名为模块的模块”。但是..。
# file test.py
import package.subpackage.module
from package.subpackage import module # Alternative
print module # Surprise here
这是个模块,但不是模块/-P8-O..
# file test.py v3
from package.subpackage.module import attribute1
print attribute1 # OK
这个管用。因此,您要么被迫一直使用过度杀伤前缀,要么使用版本 # 1中的不安全方式,而 Python 不允许您使用安全方便的方式?更好的方法,哪一个是安全的,避免不必要的长前缀是唯一的 Python 拒绝?这是因为它喜欢 import *
,还是因为它喜欢过长的前缀(这无助于实施这种做法) ?.
抱歉说了这么难听的话,但是我已经花了两天时间来处理这种愚蠢的行为了。除非我在某个地方完全错了,否则我会觉得 Python 的包和子包模型真的出了问题。
Notes
sys.path
,以避免全局副作用,也不想依赖于 *.pth
文件,这只是另一种方式玩 sys.path
与相同的全局效应。为了使解决方案干净,它必须是本地的。Python 可以处理子包,也可以不处理子包,但是它不需要使用全局配置来处理本地内容。package/subpackage/__init__.py
中使用导入,但它解决不了任何问题,它执行相同的操作,并且抱怨 subpackage
不是一个已知的模块,而 print subpackage
说它是一个模块(又是怪异的行为)。也许我是完全错误的强硬(我更喜欢这个选项) ,但是这让我对 Python 感到非常失望。
除了我试过的三种方法,还有别的方法吗? 有什么我不知道的吗?
(sigh)
——编辑—— >% ——
There is nothing like real sub‑package in Python, as all package references goes to a global dictionnary, only, which means there's no local dictionary, which implies there's is no way to manage local package reference.
你必须使用完全前缀或短前缀或别名,如:
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
Or else, a variation of the above.
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.
不是我最喜欢的类型(我喜欢每个导入实体有一个导入语句) ,但可能是我个人喜欢的那个。
Update (2012-09-14):
最后,除了一个关于布局的注释之外,在实践中看起来还不错:
from package.subpackage.module import (
attribute1,
attribute2,
attribute3,
...) # and etc.