当前位置: 首页 > 知识库问答 >
问题:

第无数次相对进口

颜永怡
2023-03-14

我来过这里:

  • http://www.python.org/dev/peps/pep-0328/
  • http://docs.python.org/2/tutorial/modules.html#包
  • Python包:相对导入
  • Python相对导入示例代码不起作用
  • python 2.5中的相对导入
  • Python中的相对导入
  • Python:禁用相对导入

还有很多URL我没有复制,有些在SO上,有些在其他网站上,当我以为我会很快找到解决方案的时候。

ImportError: attempted relative import with no known parent package
package/
    __init__.py
    subpackage1/
        __init__.py
        moduleX.py
        moduleY.py
    subpackage2/
        __init__.py
        moduleZ.py
    moduleA.py

我确实在适当的模块中制作了名为垃圾邮件和鸡蛋的函数。自然,这没有奏效。答案显然在我列出的第四个网址中,但对我来说都是校友。在我访问的一个URL上有这样的回应:

相对导入使用模块的name属性来确定该模块在包层次结构中的位置。如果模块的名称不包含任何包信息(例如,它被设置为“main”),那么相对导入将被html" target="_blank">解析为模块是顶级模块,而不管模块实际上位于文件系统的哪个位置。

上面的回应看起来很有希望,但对我来说都是象形文字。所以我的问题是,如何让Python不返回给我“非包中的尝试相对导入”?应该有一个包含-m的答案。

有人能告诉我为什么Python会给出这个错误信息吗?它所说的“非包”是什么意思?为什么以及如何定义一个“包”?以及确切的答案,用一个幼稚园的学生很容易理解的术语来表达。

共有1个答案

荆亦
2023-03-14

脚本与模块

这里有个解释。简而言之,直接运行Python文件和从其他地方导入该文件之间有很大的区别。仅仅知道文件在哪个目录中并不能确定Python认为它在哪个包中。另外,这取决于如何将文件加载到Python中(通过运行或导入)。

加载Python文件有两种方式:作为顶级脚本或作为模块。如果直接执行文件,则文件将作为顶级脚本加载,例如在命令行上键入Python myfile.py。当在其他文件中遇到import语句时,它将作为模块加载。一次只能有一个顶级脚本;顶级脚本是您运行以启动工作的Python文件。

package/
    __init__.py
    subpackage1/
        __init__.py
        moduleX.py
    moduleA.py

如果导入modulex(注意:导入,而不是直接执行),则其名称为package.subpackage1.modulex。如果导入modulea,则其名称为package.modulea。但是,如果从命令行直接运行modulex,则其名称将改为__main__,如果从命令行直接运行modulea,则其名称将为__main__。当一个模块作为顶级脚本运行时,它将丢失它的正常名称,取而代之的是__main__

不通过包含模块的包访问模块

还有一个额外的问题:模块的名称取决于它是从它所在的目录“直接”导入的,还是通过包导入的。只有当您在一个目录中运行Python并尝试在同一目录(或它的子目录)中导入文件时,这才会有所不同。例如,如果在package/subpackage1目录中启动Python解释器,然后执行import modulexmodulex的名称将只是modulex,而不是package.subpackage1.modulex。这是因为当交互式输入解释器时,Python将当前目录添加到其搜索路径中;如果它在当前目录中找到要导入的模块,它将不知道该目录是包的一部分,包信息也不会成为模块名称的一部分。

一种特殊情况是,如果您以交互方式运行解释器(例如,只需键入Python并开始动态输入Python代码)。在本例中,交互式会话的名称为__main__

对于错误信息来说,关键是:如果模块的名称没有点,它就不被认为是包的一部分。文件实际上在磁盘上的什么位置并不重要。重要的是它的名字是什么,它的名字取决于你如何加载它。

现在看看你在问题中的引用:

相对导入使用模块的name属性来确定该模块在包层次结构中的位置。如果模块的名称不包含任何包信息(例如,它被设置为'main'),那么不管模块实际上位于文件系统中的哪个位置,相关导入都会被解析为模块是顶级模块。

相对进口...

脚本不能导入相对

您可能会尝试从命令行运行modulex等。当您这样做时,它的名称被设置为__main__,这意味着它内部的相对导入将失败,因为它的名称没有显示它在包中。请注意,如果您从模块所在的同一目录运行Python并尝试导入该模块,也会发生这种情况,因为如上所述,Python将“过早”在当前目录中找到模块,而没有意识到它是包的一部分。

还要记住,当您运行交互式解释器时,交互式会话的“名称”总是__main__。因此,不能直接从交互式会话进行相对导入。相对导入仅用于模块文件中。

>

  • 如果您确实想直接运行modulex,但仍然希望将其视为包的一部分,可以执行Python-M package.subpackage1.modulex-m告诉Python将其作为模块加载,而不是作为顶级脚本加载。

    或者您实际上并不想运行modulex,您只想运行其他一些脚本,比如myfile.py,它使用modulex中的函数。如果是这种情况,请将myfile.py放在其他地方--而不是在package目录中--并运行它。如果在myfile.py中执行诸如从package.modulea导入垃圾邮件之类的操作,它将工作正常。

    注释

    >

  • 对于这两种解决方案,包目录(在您的示例中为package)必须可以从Python模块搜索路径(sys.path)访问。如果不是,您将根本无法可靠地使用包中的任何内容。

    自Python 2.6以来,用于包解析目的的模块“名称”不仅由其__name__属性决定,还由__package__属性决定。这就是为什么我避免使用显式符号__name__来引用模块的“名称”。由于Python 2.6,模块的“名称”实际上是__package__+'。+__name__,或者如果__package__none则只需__name__。)

  •  类似资料:
    • 我来过这里: http://www.python.org/dev/peps/pep-0328/ http://docs.python.org/2/tutorial/modules.html#软件包 Python包:相对导入 Python相对导入示例代码不工作 python 2.5中的相对导入 Python中的相对导入 Python:禁用相对导入 还有很多我没有复制的网址,有些在SO上,有些在其他站

    • 我正在做一个游戏,但是我在使用“相交”功能时遇到了一个问题。塞纳里奥看起来像这样;我做了一个游戏,玩家是一个长方形,目标是杀死敌人。敌人的“老板”矩形有两个“模拟”,模拟一个运动和一个攻击。这些模拟是由向量驱动的。移动是水平来回的,攻击是垂直的,一种冲锋式的交易。boss也有一个矩形的目标区域,如果被截断,“boss”将在屏幕上冲锋。现在问题来了,当我试图让它,如果球员与矩形目标区域相交,“老板”

    • 问题内容: 我有一个具有以下目录结构的go Project 我正在尝试从login.go访问功能test1。这是我所做的 但是我总能得到。我是新来的。谁能帮我得到这个错误的原因? 问题答案: 没有,Go中没有相对导入。 您应该考虑使用GOPATH来使用Abs路径: GOPATH环境变量指定工作空间的位置。在开发Go代码时,很可能需要设置唯一的环境变量。首先,创建一个工作区目录并相应地设置GOPAT

    • 然后我再做一次,但第二次完全不迭代。我花了很多时间调试它,最后将迭代程序转换为一个列表。 你们有谁知道原因吗? 编辑:对不起,如果我不清楚, 谢谢,Harendra

    • 问题内容: 为什么我不能对相同的数据进行两次迭代? 这将打印“执行一次”几次(由于数据有几行),但是根本不会打印“执行两次”。 我第一次遍历数据工作正常,但是第二次当我运行最后一个列表“针对数据行”时,此操作什么都不返回……因此一次执行它却不能两次……? 仅供参考-数据是一个csv.reader对象(如果是原因)… 问题答案: 这是因为它data是一个迭代器,你只能使用一次迭代器。例如: 如果我们

    • 问题内容: 我有一个程序,该程序每分钟通过PING检查网络中计算机的状态。每次它将向数据库插入新行,如下所示(我使用的是postgresql) 我希望结果如下 如何获得此输出? 问题答案: 这是差距和孤岛的问题。可以解决如下: dbffile演示 关键是最嵌套的子查询,在该子查询中,我使用两个函数来隔离设备上相同状态的连续出现。一旦有了价值,剩下的就很容易了。 结果