我一直在python上纠结于相对导入。
我的项目结构看起来像这样:
root_dir
├── main.py
├── Pipfile
├── Pipfile.lock
├── unit_tests
│ ├── __init__.py
│ ├── test_first.py
│ └── test_second.py
└── my_package
├── __init__.py
├── first.py
├── second.py
└── third.py
我想将一组函数从位于my_package
中的文件导入到test_first.py
中。
根据official documentation,语法应该如下:
from ..my_package import first
当我这样做时,我得到以下异常:
Traceback (most recent call last):
File "/home/user/dev/root_dir/my_package/unit_tests/first.py", line 8, in <module>
from ..my_package import first
ImportError: attempted relative import with no known parent package
我还尝试使用以下语法导入文件:
from root_dir.my_package import first
当我这样做时,我会得到以下异常:
ModuleNotFoundError: No module named 'root_dir'
值得一提的是,我正在使用pipenv
来处理虚拟环境。知道为什么会这样吗
谢谢
4条答案
按热度按时间nkoocmlb1#
首先,我会给予你的代码,为我工作。那我就简单解释一下。下面是一个简短的函数,它应该允许您从根目录导入。
解决方案
因为根目录是
test_first.py
的祖目录,所以需要转到深度2:说明
我在我的一个项目中遇到了同样的问题,并发现通过更改
sys.path
可以修复从父目录导入的问题。除非所有内容都是包的一部分,否则使用类似sys.path.append(abs_path_to_root)
的东西向根目录追加绝对路径似乎不起作用。默认情况下,Python不会在导入中访问父目录。mzmfm0qo2#
current working directory is not a package使用
os.getcwd()
查看它是什么,但它很可能是root_dir
。在这种情况下,您可以直接按名称导入顶级包,而无需相对导入;你应该直接从
my_package
导入,像这样:...或:
复制的文件树:
main.py
的内容:如果尝试执行相对导入,即:
from ..my_package import first
你会得到:kwvwclae3#
我认为问题是你的根目录不被认为是一个python模块。
为了进行相对导入,您应该将“init.py”添加到根目录。
https://docs.python.org/3/reference/import.html
jpfvwuh44#
相对导入只允许在包内进行。软件包必须是自高效的,并且只依赖于标准库或第三方软件包,无论是在全局还是虚拟环境的“lib”文件夹中。一个包不能访问它周围的任何python模块,这意味着包内的模块不能以相对的方式导入包的顶级文件夹之外的任何东西。要指定包的顶级文件夹,请在其根目录下创建
__init__.py
文件,并将以下代码放入其中:在你的例子中,你可以有两个包:'root_dir'和'my_package'。因此,在'root_dir'中创建
__init__.py
,并且您已经在'my_package'中创建了__init__.py
,并将以下内容放入其中:现在你可以有以下相对导入: