我具有以下目录结构:
root
/src
file1.py
file2.py
/libs
__init__.py
package.so
我希望在package.so
内导入file1.py
。
我尝试了以下导入语句,但无济于事:
from .libs.package import func
from libs.package import func
from .libs import package
from libs import package
我希望避免设置PYTHONPATH
/ sys.path
。
有没有简单的方法可以做到这一点?我认为问题是由于软件包是共享对象,而不仅仅是Python文件-我无权访问其源代码。
谢谢, 亚当
答案 0 :(得分:4)
如果您打算不使用sys.path.append
来导入文件,则可以使用file1.py
中的以下代码片段来做到这一点:
import imp
import os
file = os.sep+os.path.join(*os.path.realpath(__file__).split(os.sep)[:-1]+['..','libs','package.so'])
package = imp.load_source('root.libs.package', file)
print package.a()
打印<root.libs.package.a instance at 0x101845518>
。请注意,我的package.so文件只是一个定义了伪类a
的python文件,因此我可以测试将其导入。根据我的阅读,我相信您可能想要用imp.load_source
替换imp.load_dynamic
。
打破现状:
os.path.realpath(__file__).split(os.sep)[:-1]
为您提供当前正在运行的脚本所在目录的路径,作为字符串列表。
+['..','libs','package.so']
将包含父目录(..
),libs
目录以及该目录的文件名的列表连接起来,以便os.path.join将构建完整路径到package.so
文件中。
os.path.join(*[that list])
将列表元素解压缩为os.path.join
的参数,并使用os.sep
将字符串连接在一起。我还添加了前导os.sep
,因为它是绝对路径。
imp.load_source
返回一个从文件路径加载的名称为root.libs.package
的模块。
答案 1 :(得分:0)
您可以按照python文档中的描述使用相对导入:-here
它也仅适用于软件包下的目录,该目录不会要求超出导入范围。如果会发生,那么将发生此错误:-
free
您也可以参考以下问题:- value error for relative import
答案 2 :(得分:0)
为了从上面的目录导入文件,您应该使用..
根据您的情况,您需要使用以下任一行导入:
from ..libs.package import func
from ..libs import package
from root.libs.package import func
from root.libs import package
请记住,根据python文档,首选使用完整路径而不是..
,因此from root.libs
是更好的选择。
关于无法遍历:如果您的主脚本是file1.py
,则应从包含root
的目录开始,如下所示:
python -m root.src.file1 args
这样,python会将您的根视为软件包。
最后但并非最不重要的一点:在使用Python 2时,您需要将__init__.py
放在每个目录中,包括src
和root
。