我最近开始学习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#中,我们使用名称空间并包含文件,但在这里我很困惑。任何帮助将不胜感激。
答案 0 :(得分:2)
您的相对导入尝试无效,因为pkg1
和pkg2
是单独的包。相对导入仅在一个软件包中起作用。
python甚至知道
app.py
是入口点吗?
不。这只是目录中的某个.py文件。
为什么我在
,它为什么起作用pkg2.mul
中输入了fib.py
巧合。您位于app/
目录中,并且sys.path
的第一个元素是工作目录。如果您转到其他目录,则可能无法正常工作。
为什么我在
,它为什么起作用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
的第一个元素)
答案 1 :(得分:0)
基本问题是您的app
未打包(因为它缺少一个__init__.py
文件),这意味着当您进入app
目录的两个级别时,您并没有不再包含在软件包中,因此出现错误,指出您正尝试导入顶级软件包之外。
有关如何重组程序包以允许尝试执行的操作的更多信息,请参见this section on intra-package references。您还可以查看this section explaining the module search path了解更多内容。