我最近开始学习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将任何文件视为入口文件。
app.py
是切入点吗?不,我猜。pkg2.mul
中给出fib.py
时,为什么它会起作用pkg1.fib
中给出app.py
时,为什么它会起作用ext.py
和mul.py
中加入app.py
怎么办?app.py
导入pkg1.fib
(相对于app.py
)是有效的,那么fib.py
必须以不同的方式导入mul
正确吗?为什么它适用于pkg2.mul
?它真的有效吗? pkg2/
与fib.py
无关。我错过了什么吗?在打字稿中我们使用相对导入和C#我们使用命名空间和包含文件,但在这里我很困惑。任何帮助是极大的赞赏。
您的相对导入尝试不起作用,因为pkg1
和pkg2
是单独的包。相对导入仅在一个包中有效。
python甚至知道
app.py
是切入点吗?
不,它只是一些.py文件,位于目录中。
当我在
pkg2.mul
中给出fib.py
时,为什么它会起作用
巧合。您位于app/
目录中,sys.path
的第一个元素是工作目录。如果你cd到其他目录,它可能无法工作。
当我在
pkg1.fib
中给出app.py
时,为什么它会起作用
与上述相同。
如果我想在
ext.py
和mul.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
的第一个元素)
基本问题是你的app
不是包(因为它缺少一个__init__.py
文件),这意味着当你进入app
目录的两个级别时,你不再在一个包中,因此错误表明你正在尝试导入超出顶级包。
有关如何重新构建程序包以允许您尝试执行的操作的详细信息,请参阅this section on intra-package references。您还可以查看this section explaining the module search path以了解更多信息。