zoukankan      html  css  js  c++  java
  • Python包的相对导入时出现错误的解决方法

    在练习Python中package的相对导入时,即

    from . import XXX
      或者 

    from .. import XXX
      时会遇到这样两个错误:

    SystemError: Parent module '' not loaded, cannot perform relative import
      和

    ValueError: attempted relative import beyond top-level package

      其实这两个错误的原因归根结底是一样的:在涉及到相对导入时,package所对应的文件夹必须正确的被python解释器视作package,而不是普通文件夹。否则由于不被视作package,无法利用package之间的嵌套关系实现python中包的相对导入。

      文件夹被python解释器视作package需要满足两个条件:

      1、文件夹中必须有__init__.py文件,该文件可以为空,但必须存在该文件。

      2、不能作为顶层模块来执行该文件夹中的py文件(即不能作为主函数的入口)。

      补充:在"from YY import XX"这样的代码中,无论是XX还是YY,只要被python解释器视作package,就会首先调用该package的__init__.py文件。如果都是package,则调用顺序是YY,XX。

      另外,练习中“from . import XXX”和“from .. import XXX”中的'.'和'..',可以等同于linux里的shell中'.'和'..'的作用,表示当前工作目录的package和上一级的package。

      举个例子:

      目录树

      testIm/

      --init.py

      --main.py : from Tom import tom

      --Tom/

        --init.py : print("I'm Tom's init!")

        --tom.py : from . import tomBrother, from .. import Kate,print("I'm Tom!")

        --tomBrother.py print(I'm Tom's Brother!)

      --Kate/

        --init.py : print("I'm Kate's init!")

        --kate.py

      运行文件:main.py

      结果:

    复制代码
    I'm Tom's init!
    I'm Tom's Brother!
    Traceback (most recent call last):
    File "D:PythonLearningTestIm2main.py", line 3, in
    from cat import cat
    File "D:PythonLearningTestIm2catcat.py", line 4, in
    from .. import dog
    ValueError: attempted relative import beyond top-level package

    复制代码
    可以看到from . import tomBrother顺利执行,首先执行了Tom文件夹下的__init__.py文件,后来执行了tomBrother.py文件,但是当执行到“from .. import dog”时报错,这是因为我们是在TestIm文件夹下把main.py文件作为主函数的入口执行的,因此尽管TestIm文件夹中有__init__.py文件,但是该文件夹不能被python解释器视作package,即Tom package不存在上层packge,自然会报错,相对导入时超出了最高层级的package。

    修改方法:

    目录树

      test/

      --main.py : from testIm.Tom import tom

      --testIm/

        --init.py

        --Tom/

          --init.py : print("I'm Tom's init!")

          --tom.py : from . import tomBrother, from .. import Kate,print("I'm Tom!")

          --tomBrother.py print(I'm Tom's Brother!)

        --Kate/

        --init.py : print("I'm Kate's init!")

        --kate.py

      运行文件:main.py

    结果:  

    I'm top's init!
    I'm Tom's init!
    I'm Tom's Brother!!
    I'm Kate's init!
    I'm Tom!
    即主函数入口不在TestIm中,则TestIm和其同样包含__init__.py文件的子文件夹都被python解释器视作package,形成相应的嵌套关系。可以正常使用from . import XXX和from .. import XXX。

  • 相关阅读:
    leetcode33. Search in Rotated Sorted Array
    pycharm 设置sublime text3 monokai主题
    django class Meta
    leetcode30, Substring With Concatenation Of All Words
    Sublime text3修改tab键为缩进为四个空格,
    sublime text3 python打开图像的问题
    安装上imesupport输入法依然不跟随的解决办法,
    sublime text3 的插件冲突弃用问题,
    sublime text3 BracketHighlighter括号匹配的设置
    windows 下wget的使用
  • 原文地址:https://www.cnblogs.com/cosiray/p/9995601.html
Copyright © 2011-2022 走看看