Python 模块相对引用

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python 模块相对引用相关的知识,希望对你有一定的参考价值。

文件结构如下

python_directory/
├── __init__.py
└── app
    ├── __init__.py
    ├── sub1
    │?? ├── __init__.py
    │?? └── mod1.py
    └── sub2
        ├── __init__.py
        ├── mod2.py

除了 mod1.py,其他文件内容都为空。

mod1.py

print('__name__: {}'.format(__name__))
print('__package__: {}'.format(__package__))
from ..sub2 import mod2
print('Import Successfully!')

如果 __package__ 不为空,相对引用会根据 __package__ 而不是 __name__[2]。

Relative Import In Non-Package

如果直接执行一个模块,那么它的 __name____main__。Python 会认为这个模块是一个最顶层的模块,而不管这个模块在文件系统中的实际位置[1]。

$ pwd
/path_to/python_directory

$ python app/sub1/mod1.py 
__name__: __main__
__package__: None
Traceback (most recent call last):
  File "app/sub1/mod1.py", line 3, in <module>
    from ..sub2 import mod2
ValueError: Attempted relative import in non-package

一个最顶层的模块 -- 我理解为 Python 把这个模块复制到在一个单独的目录中然后再执行,由于该目录下只有这个一个模块,
所以它不是一个 package。

Beyond Top Level Package

$ pwd
/path_to/python_directory/app

$ python -m sub1.mod1
__name__: __main__
__package__: sub1
Traceback (most recent call last):
  File "/usr/local/Cellar/python/2.7.13/Frameworks/Python.framework/Versions/2.7/lib/python2.7/runpy.py", line 174, in _run_module_as_main
    "__main__", fname, loader, pkg_name)
  File "/usr/local/Cellar/python/2.7.13/Frameworks/Python.framework/Versions/2.7/lib/python2.7/runpy.py", line 72, in _run_code
    exec code in run_globals
  File "/path_to/python_directory/app/sub1/mod1.py", line 4, in <module>
    from ..sub2 import mod2
ValueError: Attempted relative import beyond toplevel package

由于 -m sub1.mod1,Python 将 package 的顶层视为 sub1,而 ..sub2 位于 app/,超过了当前的最顶层 sub1,所以报错。

└── app
    ├── __init__.py
    ├── sub1
    │?? ├── __init__.py
    │?? └── mod1.py
    └── sub2

正确的调用

$ pwd
/path_to/python_directory

$ python -m app.sub1.mod1
__name__: __main__
__package__: app.sub1
Import Successfully!

此时 ..sub2 相当于 app.sub2

参考

  1. PEP 328 -- Imports: Multi-Line and Absolute/Relative
  2. PEP 366 -- Main module explicit relative imports

以上是关于Python 模块相对引用的主要内容,如果未能解决你的问题,请参考以下文章

python-模块

python-模块

python中的模块包

Python 模块引用和编译

Python记录器,相对时间(relativeCreated),可以重设引用吗?

常用模块模块引用与查找路径