了解包导入

问题描述 投票:1回答:2

我最近开始学习python。我有打字稿和C#背景。我试图理解包和导入语句。以下是我创建的非常基本的文件夹结构,我对此几乎没有问题

app/
 |-> pkg1/
      |-> fib.py
      |-> __init__.py
 |- >pkg2/
      |-> mul.py
      |-> __init__.py
 |-> app.py
ext/
 |-> ext.py
 |-> __init__.py 

fib.py
------
from pkg2.mul import mul
// from ..pkg2.mul import mul -> Error: attempted relative import beyond top-level package
// but this should work as per docs https://docs.python.org/3/tutorial/modules.html#intra-package-references
// can someone tell why do I get this error?

def fib(n):
    return mul(n) * 2

mul.py
------
def mul(n):
    return n * 10

app.py
------
from pkg1.fib import fib
print(fib(1))

我读过Python将任何文件视为入口文件。

  • python甚至知道app.py是切入点吗?不,我猜。
  • 当我在pkg2.mul中给出fib.py时,为什么它会起作用
  • 当我在pkg1.fib中给出app.py时,为什么它会起作用
  • 如果我想在ext.pymul.py中加入app.py怎么办?
  • 根据文件夹结构,如果app.py导入pkg1.fib(相对于app.py)是有效的,那么fib.py必须以不同的方式导入mul正确吗?为什么它适用于pkg2.mul?它真的有效吗? pkg2/fib.py无关。

我错过了什么吗?在打字稿中我们使用相对导入和C#我们使用命名空间和包含文件,但在这里我很困惑。任何帮助是极大的赞赏。

python
2个回答
2
投票

您的相对导入尝试不起作用,因为pkg1pkg2是单独的包。相对导入仅在一个包中有效。

python甚至知道app.py是切入点吗?

不,它只是一些.py文件,位于目录中。

当我在pkg2.mul中给出fib.py时,为什么它会起作用

巧合。您位于app/目录中,sys.path的第一个元素是工作目录。如果你cd到其他目录,它可能无法工作。

当我在pkg1.fib中给出app.py时,为什么它会起作用

与上述相同。

如果我想在ext.pymul.py中加入app.py怎么办?

你必须打包ext并将其作为app的依赖项包含在内。

根据文件夹结构,如果app.py导入pkg1.fib(相对于app.py)是有效的,那么fib.py必须以不同的方式导入mul正确吗?为什么它适用于pkg2.mul?它真的有效吗? pkg2/fib.py无关。

它不是相对于app.py导入的。它们都是从cwd导入的(检查使用sys.path显示的python -m site的第一个元素)


0
投票

基本问题是你的app不是包(因为它缺少一个__init__.py文件),这意味着当你进入app目录的两个级别时,你不再在一个包中,因此错误表明你正在尝试导入超出顶级包。

有关如何重新构建程序包以允许您尝试执行的操作的详细信息,请参阅this section on intra-package references。您还可以查看this section explaining the module search path以了解更多信息。

© www.soinside.com 2019 - 2024. All rights reserved.