我正在尝试理解Python中的import-logic。
如果你把this教程作为参考,我想你将无法做到,例如声明:
from sound.effects import echo
至少,不是来自包装内。
然而,Suds(我感兴趣的一个包)会做类似here
的事情suds / suds / builder.py的片段:
from logging import getLogger
from suds import *
from suds.sudsobject import Factory
..
文件夹结构:
suds/
...no_package_init_file_here...
suds/
__init__.py
builder.py
sudsobject.py
...
这是怎么做的,为什么会这样?
我认为在包中使用容器包名称是“不允许的”。根据经验。
现在,有一件事我能想到:suds会将自己添加到PYTHONPATH中,从而可以进入每个级别。这是什么原因?
而且,你们认为Suds在这里有一个聪明的解决方案吗?或者有点hacky?
提前致谢。
答案 0 :(得分:0)
支持两种解决方案。从您可以使用的包中:
from mypackage import mymodule
或
import mymodule
如果您只想从模块导入单个类
from mypackage import mymodule.myclass
或
import mymodule.myclass
答案 1 :(得分:0)
听起来像pythonpath ..
在研究了一下之后,我发现这一切都取决于PYTHONPATH或sys.path
。
因此,当from sound.effects import echo
中找到sound
时,sound
在sys.path
包(第一个示例)中起作用。
只有当sound
位于sys.path
中存在的目录中时,才会发生这种情况。
相对于已执行的脚本
当从可以找到声音包的目录中调用执行的脚本(.py文件或解释器)时,不会引发错误。这是因为该目录是sys.path
列表中的第一个元素。
但是,当执行的脚本在包本身内部时,它将找不到sound
,因此将引发ImportError: No module named sound
。当然,除非sound
包含在sys.path
的其他级别(例如/usr/lib/python2.6/dist-packages
)。
关于suds
现在,对于suds
,这个导入语句是正确的。这是因为suds
包存在于PYTHONPATH(sys.path
)中。这样,from suds.sudsobject import Factory
在PYTHONPATH(dist-packages)中调用suds的版本。
额外:
就我而言,我想修改suds
源代码,因此我在我的lib中放置了整个目录的副本:my_package/lib/suds/
。然而,调用脚本(.py)可能找不到suds
,因为它太深了1级。然后导致导入错误,因为无法正确加载肥皂
如果您不想suds
来自dist-packages
,可以手动将其添加到sys.path
:
import sys, os
suds_parent = os.path.join(os.path.dirname(__file__), 'lib')
if suds_parent not in sys.path:
sys.path.append(suds_parent)