繁体   English   中英

ValueError:尝试在顶级包python之外进行相对导入

[英]ValueError: attempted relative import beyond top-level package python

我有一个这样的目录结构。

Chatbot/
   utils/
     abc.py
   projects/
      proj1/
        utils/
          __init__.py
          data_process.py
        components/
          class1.py

我的结构中有两个utils文件夹,一个在顶层,一个在我的项目文件夹中。

现在我想在class1.py导入data_process.py文件。 所以我试过这样

from utils.data_process import DataProcess

但它引用了顶级utils文件夹,甚至 VSCode 也无法识别它。 我尝试在utils文件夹中创建__init__.py文件,但仍然无效。

我尝试使用空的__init__.py然后放置此内容

from . import data_process
__all__ = ['data_proces']

然后

from .data_process import DataPreprocess
__all__ = ['DataPreprocess']

然后我试过了

from ..utils.data_process import DataProcess

VSCode 正在识别这一点,但它无法正常工作并引发错误

ValueError: attempted relative import beyond top-level package

即使我尝试将名称 utils 更改为其他名称,但仍然存在相同的问题

我该如何解决这个问题?

python 模块由一个名为__init__.py的特殊文件定义,该文件应存在于所有子目录中。 因此,您的文件结构将是:

Chatbot/
   __init__.py
   utils/
     __init__.py
     abc.py
   projects/
      __init__.py
      proj1/
        __init__.py
        utils/
          __init__.py
          data_process.py
        components/
          __init__.py
          class1.py
          class2.py

现在,您可以进行相对导入,例如:

  • 使用. 用于导入同一目录中的内容。 例子:
# file Chatbot/projects/proj1/components/class2.py
from .class1 import *
  • 同样,使用..表示二级,使用...表示三级,依此类推!

例如:

# file Chatbot/projects/proj1/components/class2.py
from ..utils.data_process import * # import from data_process.py
# there will be four "." earlier I made a counting mistake
from ....utils.abc import * # import something from abc.py

编码约定

在编写 python 模块/包时,您可能需要遵循PEP8 约定

此外,我相信您正在尝试使用您的包Chatbot来做不同的项目,对吗? 然后,最好为Chatbot设置PYTHONPATH并执行所有项目,然后单独导入。

编辑:上传虚拟文件

即使使用两个utils目录,我也能够无缝地处理这个项目。 项目结构:

在此处输入图片说明

main文件及其输出:

# file main.py
from chatbot.utils.abc import hello as a1
from chatbot.projects.proj1.components.class1 import super_hello
from chatbot.projects.proj1.utils.data_process import hello as b1

print(a1(), b1())
print(super_hello())

在此处输入图片说明

同样,如果您在PYTHONPATH下有chatbot ,您可以从您的设备的任何位置调用该项目。

代码详细信息和文件添加到我的github帐户中以获取详细信息。

sys.path是 Python 搜索模块和包的地方,它按顺序执行

所以你可以将...../proj1/放在列表的开头,当python开始搜索时,它会首先找到该路径中的utils文件夹!

import sys
sys.path.insert(0, r'...../proj1/')

但这会导致另一个问题,python 总是先在该文件夹中查找utils ,这不是您想要的。

解决方案 1

绝对导入:

from Chatbot.projects.proj1.utils.data_process import DataProcess

解决方案 2

使用@Mr.Hobo 提到的相对导入。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM