• 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
  • 相关阅读:
    揭开正则表达式的神秘面纱
    海量数据库的查询优化及分页算法方案
    ASP.NET纯数字验证码
    ASP.NET四种页面导航方式之比较与选择
    C#数据结构之队列
    if exists
    使用tfs online做代码片段笔记管理
    强制删除数据库
    C# GetType()
    TreeView
  • 原文地址:https://www.cnblogs.com/jay54520/p/8438228.html
Copyright © 2020-2023  润新知