ValueError:尝试在顶级包之外进行相对导入 [英] ValueError: attempted relative import beyond top-level package

查看:75
本文介绍了ValueError:尝试在顶级包之外进行相对导入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在玩 Python 的导入系统以更好地理解它是如何工作的,但我遇到了另一个问题.我有以下结构

pkg/__init__.pypyd.py子包/__init__.py一个.pyb.py

a.py 里面我有以下代码:

来自 .进口乙从 .. 进口 d

c.py 里面我有以下内容:

import subpkg.a

现在我收到以下错误:

<块引用>

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

但是为什么?我该如何解决?我正在从 IDLE 运行 c.py,并且 pkg 应该被视为一个包,因为它有 __init__.py 文件.>

第一次导入工作正常,但以下内容不起作用:

from .. import d

因为我试图从父包中导入一些东西,但显然我不能,出于某种奇怪的原因.

解决方案

这让我怀疑自己的精神错乱.

问题源于人们的困惑,即人们错误地将相对导入视为路径相对,而不是.

相对导入取决于运行文件的位置.

这个答案更深入地解释了python如何模块确实有效,但总结一下.

  1. 加载文件时,会为其指定一个名称:
    • 如果它是作为顶级脚本加载的(直接运行),它的名字是__main__.
    • 如果它作为模块加载(with import),它的名字是文件名,前面是它所属的任何包/子包的名称,用点分隔 - pkg.subpkg.a
  2. 如果您执行 from .. 文件名中必须至少有 2 个点.来自 ... - 3 个点.

现在是有趣的部分.

如果你直接运行 c.py,那么它的名字是 __main__ 并且 a.pysubpkg.a.

根据第二条语句,subpkg.a 的名称中必须至少有 2 个点才能在其中运行 from ...

修复

pkg 之外创建一个新文件,比如 main.py

pkg/__init__.pypyd.py子包/__init__.py一个.pyb.py主文件

在 main.py 中

import pkg.c

如果我们运行 main.py,它会得到名称 __main__,而 a.py 会得到 pkg.subpkg.a.根据第二条语句,它现在在名称中有 2 个点,我们可以执行 from ..

还有一件事.现在 c.py 作为模块加载,我们必须使用 from 来加载 a.py.

from .subpkg import a

I was playing the the Python's import system in order to understand better how it works, and I encountered another problem. I have the following structure

pkg/
    __init__.py
    c.py
    d.py

    subpkg/
        __init__.py
        a.py
        b.py

Inside a.py I have the following code:

from . import b
from .. import d

And inside c.py I have the following:

import subpkg.a

Now I receive the following error:

ValueError: attempted relative import beyond top-level package

But why? How can I solve it? I am running c.py from the IDLE, and pkg should be considered a package, since it has the __init__.py file.

The first import works fine, but it's the following that doesn't work:

from .. import d

Because I am attempting to import something from a parent package, but apparently I cannot, for some weird reason.

解决方案

This had me question my insanity.

The problem stems from the confusion that people mistakenly take the relative import as path relative which is not.

Relative imports depend on the location of the file that is run.

This answer goes deeper into explaining how the python modules actually work, but to summarize.

  1. When a file is loaded, it is given a name:
    • If it was loaded as the top-level script (run directly), its name is __main__.
    • If it was loaded as a module (with import), its name is the filename, preceded by the names of any packages/subpackages of which it is a part, separated by dots - pkg.subpkg.a
  2. If you do a from .. there must be at least 2 dots in the file name. from ... - 3 dots.

Now comes the funny part.

If you run c.py directly, then it is given the name __main__ and a.py has subpkg.a.

As per the 2nd statement, you must have at least 2 dots in the name of subpkg.a to run from .. inside it.

The fix

Create a new file outside the pkg, say main.py

pkg/
    __init__.py
    c.py
    d.py

    subpkg/
        __init__.py
        a.py
        b.py
main.py

Inside main.py

import pkg.c

If we run main.py, it get's the name __main__, and a.py get's pkg.subpkg.a. As per the 2nd statement it now has 2 dots in the name and we can do the from ..

One more thing. Now that c.py is loaded as a module, we have to use from to load a.py.

from .subpkg import a

这篇关于ValueError:尝试在顶级包之外进行相对导入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆