Python 了解软件包导入

Python 了解软件包导入,python,Python,我最近开始学习python。我确实有打字脚本和C#背景。我试图理解packages和imports语句。下面是我创建的非常基本的文件夹结构,我对此没有什么问题 app/ |-> pkg1/ |-> fib.py |-> __init__.py |- >pkg2/ |-> mul.py |-> __init__.py |-> app.py ext/ |-> ext.py |-> __in

我最近开始学习python。我确实有打字脚本和C#背景。我试图理解packages和imports语句。下面是我创建的非常基本的文件夹结构,我对此没有什么问题

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
    是入口点?我想没有
  • 当我在
    fib.py
  • 当我在
    app.py
  • 如果我想将
    ext.py
    包含在
    mul.py
    app.py
  • 根据文件夹结构,如果
    app.py
    导入
    pkg1.fib
    (相对于
    app.py
    )有效,则
    fib.py
    必须以不同的方式导入
    mul
    ,是否正确?为什么它为pkg2.mul工作?它真的有效吗
    pkg2/
    fib.py
    无关

我错过什么了吗?在typescript中,我们使用相对导入,而C#使用名称空间并包含文件,但在这里我感到相当困惑。非常感谢您的帮助。

您的相对导入尝试无效,因为
pkg1
pkg2
是单独的包。相对导入仅在一个包中工作

python是否知道
app.py
是入口点

不,只是目录中的一些.py文件

当我在
fib.py

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

当我在
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导入的(检查使用
python-m站点显示的
sys.path
的第一个元素)

基本问题是您的
应用程序不是包(因为它缺少
\uu init\uuuuu.py
文件)这意味着,当您进入
app
目录的两个级别时,您不再位于包中,因此会出现错误,表明您正在尝试导入顶级包之外的内容


有关如何重新构造包以允许您尝试执行的操作的更多信息,请参阅。您还可以查看更多的上下文

这可能有助于你达到更高的水平,但这可能有助于你使用基本功能。看起来你的
应用程序中可能缺少
\uuu init\uuuuuuuuuuy.py
directory@Hoog我是否需要app/中的init.py,因为它是我的主脚本所在的位置。我认为如果你想把它做成软件包,需要init.py。我不认为我们需要把它做成软件包。你可以详细解释一下这句话吗?你必须把ext打包,并把它作为应用程序的依赖项。或者任何引用也有帮助,我假设“ext”是“外部依赖”的缩写。最佳实践是将源代码保存在一个完全独立的目录/项目中。任何想要导入ext并将其用作库的包都应该在其元数据中指定依赖项(您可以在
setup.py的
install\u requires
中提到它)