(子)模块中的 Python 脚本可以从其目录层次结构中的上游导入吗?
Can a Python script in a (sub)module import from upstream in its directory hierarchy?
我知道 SO 上有大量与 Python 和导入相关的帖子,但似乎有相当多的帖子在询问关于创建实际导入 rules/procedures 的问题Python 包(与仅包含多个目录和 python 文件的项目相比)。我是 Python 的新手,只需要一些更基本的说明,说明在项目目录中多个 py 文件的上下文中,关于 access/importing 什么是可能的,什么是不可能的。
假设您有以下项目目录(需要说明的是,这不是 sys.path 上某处的包,而是在您的桌面上):
myProject/
├── __init__.py
├── scriptA.py
└── subfolder
├── __init__.py
└── scriptB.py
└── subsubfolder
├── __init__.py
└── scriptC.py
└── foo.py
如果 scriptC.py
是 运行 直接通过$ python scriptC.py
并且在 subsubfolder
目录中,如果我在 运行 时间通过 [=18= 添加父目录和 scriptB.py
的路径到 Python 路径] ?
但是,scriptC.py
可以导入 foo.py
或 scriptB.py
可以导入 scriptC.py
或 foo.py
而无需处理 sys.path
,对吗?只需使用相对导入路径即可访问相邻的 py 文件和子目录中的 py 文件,你不能导入位于父目录或同级目录中的 python 脚本(不使用 sys.path)?
什么是可能的
任何东西。
不,真的。如果你想要一些灵感,请参阅 the imp
module, the the imputil
module -- take a look at how the zipimport
module 的内容。
如果您可以在变量中获取包含模块代码的字符串,则可以使用上述方法将模块放入 sys.modules
,并可能在途中使用 the ast
module 修改其内容.
在父目录中查找的自定义导入挂钩?在 运行 可能性范围内。
什么是最佳实践
您提出的建议实际上并不是好的做法。最佳实践方法看起来更像以下内容:
myProject/
├── setup.py
└── src/
├── moduleA.py
└── submodule/
├── __init__.py
├── moduleB.py
└── subsubmodule/
├── __init__.py
└── moduleC.py
在这里,您项目的顶部始终在 myProject/src
。如果您使用 setup.py
将 moduleA:main
、submodule.moduleB:main
和 submodule.subsubmodule.moduleC:main
配置为入口点(可能命名为 scriptA
、scriptB
和 scriptC
),那么当用户 运行 如此命名的(由 setuptools 自动生成的)脚本时,将调用每个模块中名为 main
的函数。
使用此布局(并使用适当的设置工具),您的 moduleC.py
绝对可以 import moduleA
或 import submodule.moduleB
.
另一种方法,不涉及入口点,调用您的 moduleC.py
中的代码(同时保持模块的预期层次结构完整,并假设您在 python setup.py develop
具有的 virtualenv 中一直 运行) 像这样:
python -m submodule.subsubmodule.moduleC
我知道 SO 上有大量与 Python 和导入相关的帖子,但似乎有相当多的帖子在询问关于创建实际导入 rules/procedures 的问题Python 包(与仅包含多个目录和 python 文件的项目相比)。我是 Python 的新手,只需要一些更基本的说明,说明在项目目录中多个 py 文件的上下文中,关于 access/importing 什么是可能的,什么是不可能的。
假设您有以下项目目录(需要说明的是,这不是 sys.path 上某处的包,而是在您的桌面上):
myProject/
├── __init__.py
├── scriptA.py
└── subfolder
├── __init__.py
└── scriptB.py
└── subsubfolder
├── __init__.py
└── scriptC.py
└── foo.py
如果 scriptC.py
是 运行 直接通过$ python scriptC.py
并且在 subsubfolder
目录中,如果我在 运行 时间通过 [=18= 添加父目录和 scriptB.py
的路径到 Python 路径] ?
但是,scriptC.py
可以导入 foo.py
或 scriptB.py
可以导入 scriptC.py
或 foo.py
而无需处理 sys.path
,对吗?只需使用相对导入路径即可访问相邻的 py 文件和子目录中的 py 文件,你不能导入位于父目录或同级目录中的 python 脚本(不使用 sys.path)?
什么是可能的
任何东西。
不,真的。如果你想要一些灵感,请参阅 the imp
module, the the imputil
module -- take a look at how the zipimport
module 的内容。
如果您可以在变量中获取包含模块代码的字符串,则可以使用上述方法将模块放入 sys.modules
,并可能在途中使用 the ast
module 修改其内容.
在父目录中查找的自定义导入挂钩?在 运行 可能性范围内。
什么是最佳实践
您提出的建议实际上并不是好的做法。最佳实践方法看起来更像以下内容:
myProject/
├── setup.py
└── src/
├── moduleA.py
└── submodule/
├── __init__.py
├── moduleB.py
└── subsubmodule/
├── __init__.py
└── moduleC.py
在这里,您项目的顶部始终在 myProject/src
。如果您使用 setup.py
将 moduleA:main
、submodule.moduleB:main
和 submodule.subsubmodule.moduleC:main
配置为入口点(可能命名为 scriptA
、scriptB
和 scriptC
),那么当用户 运行 如此命名的(由 setuptools 自动生成的)脚本时,将调用每个模块中名为 main
的函数。
使用此布局(并使用适当的设置工具),您的 moduleC.py
绝对可以 import moduleA
或 import submodule.moduleB
.
另一种方法,不涉及入口点,调用您的 moduleC.py
中的代码(同时保持模块的预期层次结构完整,并假设您在 python setup.py develop
具有的 virtualenv 中一直 运行) 像这样:
python -m submodule.subsubmodule.moduleC