无法从子文件夹//相对导入错误运行Python3脚本
我有这样一个简单的项目结构:无法从子文件夹//相对导入错误运行Python3脚本,python,python-3.x,Python,Python 3.x,我有这样一个简单的项目结构: ➜ (venv:evernote) evernote_bear_project git:(master) ✗ tree | grep -v pyc . ├── README.md ... (snip) ... ├── manage.py ├── sample │ ├── EDAMTest.py <==== here is an import that won't work │ └── enlogo.png └── util ├── __
➜ (venv:evernote) evernote_bear_project git:(master) ✗ tree | grep -v pyc
.
├── README.md
...
(snip)
...
├── manage.py
├── sample
│ ├── EDAMTest.py <==== here is an import that won't work
│ └── enlogo.png
└── util
├── __init__.py
├── files.py <====== This is being imported
└── test_files.py
当我试图从命令行中的项目根文件夹中运行python sample/EDAMTest.py
时,我收到一个错误消息:
ValueError: attempted relative import beyond top-level package
我知道这个问题已经问过很多次了,但我还是不明白
由于我是从项目根目录运行脚本,据我所知,Python
应该能够“知道”当我尝试从..util.files import*导入时,它应该上升一个目录,不是吗
编辑
谢谢你的回答
因此,我从链接中了解到:
我通过python-sample/EDAMTest.py
直接运行模块sample/EDAMTest.py
,这意味着
模块的\uuuu name\uuuuu
是\uuuuu main\uuuu
现在路径(sample/
)可以说是我的“根”李>
所以现在Python只搜索这个路径和它下面的任何路径来查找模块/包。因此,错误消息尝试在顶级包之外进行相对导入,因此它不能再上一级,因为它已经在根目录下了
此外,Python不能“向上”查找一个级别,因为此语法from..util.files import*
在目录中没有向上一个级别,但在模块/包列表中它保留在“导入搜索路径”(sys.path)上
正确吗?sys.path.append()
是一个调整,如果您的目录结构是固定的,您对此无能为力
否则,您可以尝试重新排列文件夹。最简单的方法是在sample下移动util,另一种方法是将两个文件夹都设置为一个更大的包的psrt
另外,import*
也未启用 相对导入语法用于从同一软件包而不是从文件系统导入其他模块
取决于你想要什么,你可以
修复包,使相对导入工作
将\uuuu init\uuuuu.py
文件放在项目根目录和sample目录中,并从一个级别运行脚本。这似乎不是你想要的
告诉python在哪里可以找到包
设置PYTHONPATH环境变量,以便python可以找到包
PYTHONPATH='.':$PYTHONPATH python samples/EDAMTest.py
安装util
,以便python可以找到它
添加一个安装脚本并使用它安装util
软件包,避免设置PYTHONPATH。“相对导入语法用于从同一软件包导入其他模块,而不是从文件系统导入。”
Put __init__.py in your subfolders, which will make them package.
__init__.py can be an empty file but it is often used to perform
setup needed for the package(import things, load things into path, etc).
However you can import File into your __init__.py to make it
available at the package level:
# in your __init__.py
from util import files
# now import File from util package
from util import files
of if you want to import some specific method or class, you can do
from util.files import some_function
Another thing to do is at the package level make util/modules
available with the __all__ variable. When the interpeter sees
an __all__ variable defined in an __init__.py it imports the
modules listed in the __all__ variable when you do:
from package import *
__all__ is a list containing the names of modules that you want to be
imported with import * so looking at our above example again if we
想要导入utilall变量中的子模块
在util/init中,.py将是:
__all__ = ['files', 'test_files']
With the __all__ variable populated like that, when you perform
from util import *
它将导入文件和测试文件。感谢您的详细和非常有用的解释。-不过有一点值得注意:它不应该是\uuuu init\uuuu.py
,而不是init.py
?不知何故,编辑器忽略了init的破折号。我把一切都写下来了。它解决了你的问题吗?
__all__ = ['files', 'test_files']
With the __all__ variable populated like that, when you perform
from util import *