我有一个简单的项目结构,如下所示:
➜ (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
现在我在sample/EDAMTest.py
中有一个相对重要的地方:
from ..util.files import *
当我尝试在命令行中从项目根文件夹运行python sample/EDAMTest.py
时,出现错误消息:
ValueError: attempted relative import beyond top-level package
我知道这个问题已经问了很多遍了,但是我还是不明白。
由于我是从项目根目录运行脚本,因此,根据我的理解,Python
应该能够“知道”当我尝试导入from ..util.files import *
时,脚本应该向上移动{{ 1}},不是吗?
感谢所有答案。
所以我从链接above中了解的是:
我直接通过directory
运行模块sample/EDAMTest.py
,这意味着
python sample/EDAMTest.py
是__name__
__main__
)是我的“根”。 因此,现在Python仅搜索此路径及其下的任何路径以查找模块/软件包。因此,错误消息sample/
由于它已经在根目录上了,因此它不能再上一层。
Python也无法在“上”一级查找,因为此语法attempted relative import _beyond top-level package_
不在目录中上一级,但是在模块/软件包列表中,它始终位于“导入搜索路径”(sys.path)?
对吗?
答案 0 :(得分:0)
sys.path.append()
是一个调整,如果您的目录结构是固定的,那么您将无能为力。
否则,您可以尝试重新排列文件夹。最简单的方法是将util移至sample下,另一个选择是将两个文件夹的psrt都设置为较大的包。
也未检查import *
。
答案 1 :(得分:0)
相对导入语法用于从同一软件包而不是文件系统中导入其他模块。
根据您的需求,您可以...
将__init__.py
文件放在项目根目录和示例目录中,并从上一层运行脚本。这似乎不是您想要的。
设置PYTHONPATH环境变量,以便python可以找到软件包。
PYTHONPATH='.':$PYTHONPATH python samples/EDAMTest.py
util
,以便python可以找到它添加设置脚本并使用它来安装util
软件包,并避免设置PYTHONPATH。
答案 2 :(得分:0)
“相对导入语法用于从同一软件包而不是从文件系统中导入其他模块。”,正如乔治·G所说的那样。
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
希望使用 all 变量导入子模块 在util / init .py中为:
__all__ = ['files', 'test_files']
With the __all__ variable populated like that, when you perform
from util import *
它将导入文件和test_files。