什么是python的相对导入呢?

“相对”跟linux的相对路径很像,在使用import语句的时候,可以使用"." 和 "..",且可以使用"..."来调用上两级的目录中的模块。


测试目录:

├── func_pkg
│   ├── a
│   │   ├── a1.py
│   │   ├── a1.pyc
│   │   ├── a2.py
│   │   ├── a2.pyc
│   │   ├── __init__.py
│   │   └── __init__.pyc
│   ├── b
│   │   ├── b1.py
│   │   ├── b1.pyc
│   │   ├── b2.py
│   │   ├── b2.pyc
│   │   ├── c
│   │   │   ├── c1.py
│   │   │   ├── c1.pyc
│   │   │   ├── c2.py
│   │   │   ├── c2.pyc
│   │   │   ├── __init__.py
│   │   │   └── __init__.pyc
│   │   ├── __init__.py
│   │   └── __init__.pyc
│   ├── __init__.py
│   ├── __init__.pyc
│   └── top.py       # incorrect
├── __init__.py
└── top.py



个人认为相对导入适合做工具模块,供其他程序使用来使用。因为它有以下限制:

  1. 使用相对导入的目录的平级目录内的所有py文件不允许单独执行,如下目录结构中运行func_pkg/top.py 会报错:
    Traceback (most recent call last):
      File "func_pkg/top.py", line 1, in <module>
        from b.c.c2 import *
      File "/home/will/test/r_import/func_pkg/b/c/c2.py", line 1, in <module>
        from ..b2 import b2, a1, a2
      File "/home/will/test/r_import/func_pkg/b/b2.py", line 1, in <module>
        from ..a.a1 import a1
    ValueError: Attempted relative import beyond toplevel packag

  2. 忌两个py文件循环导入,如: 
    # cat a/a1.py
    from a2 import a2
    a1 = 1
    
    # cat a/a2.py
    from a1 import a1
    a2 = 1
  3. 使用相对导入非本级目录的py也禁止单独运行:
    # cat b2.py
    from ..a.a1 import a1
    from ..a.a2 import a2
    
    b2 = 3
    
    # python b2.py
    Traceback (most recent call last):
      File "b2.py", line 1, in <module>
        from ..a.a1 import a1
    ValueError: Attempted relative import in non-package

Logo

更多推荐