了解包裹进口

时间:2019-04-18 18:26:14

标签: python

我最近开始学习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#中,我们使用名称空间并包含文件,但在这里我很困惑。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:2)

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

  

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

不。这只是目录中的某个.py文件。

  

为什么我在pkg2.mul中输入了fib.py

,它为什么起作用

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

  

为什么我在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的第一个元素)

答案 1 :(得分:0)

基本问题是您的app未打包(因为它缺少一个__init__.py文件),这意味着当您进入app目录的两个级别时,您并没有不再包含在软件包中,因此出现错误,指出您正尝试导入顶级软件包之外。

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