Weibw's World Weibw's World
首页
  • HTML
  • Python

    • Python基础知识
    • Python CookBook第三版
    • Flask
  • MySQL

    • MySQL基础知识
    • MySQL调优
    • MySQL面试题
算法
  • FineReport
  • Kettle
  • Git
  • 微信公众号文章
  • 优秀博客文章
  • 其他
收藏夹
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Weibw

一个没有梦想的咸鱼
首页
  • HTML
  • Python

    • Python基础知识
    • Python CookBook第三版
    • Flask
  • MySQL

    • MySQL基础知识
    • MySQL调优
    • MySQL面试题
算法
  • FineReport
  • Kettle
  • Git
  • 微信公众号文章
  • 优秀博客文章
  • 其他
收藏夹
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 《Flask》

  • 《Python Cookbook》第三版

    • 第一章:数据结构与算法

    • 第二章:字符串和文本

    • 第三章:数字日期和时间

    • 第四章:迭代器与生成器

    • 第五章:文件与IO

    • 第六章:数据编码和处理

    • 第七章:函数

    • 第八章:类与对象

    • 第九章:元编程

    • 第十章:模块与包

      • 构建一个模块的层级包
      • 控制模块被全部导入的内容
      • 使用相对路径名导入包中子模块
        • 问题
        • 解决方案
        • 讨论
      • 将模块分割成多个文件
      • 利用命名空间导入目录分散的代码
      • 重新加载模块
      • 运行目录或压缩文件
      • 读取位于包中的数据文件
      • 将文件夹加入到syspath
      • 通过字符串名导入模块
      • 通过钩子远程加载模块
      • 导入模块的同时修改模块
      • 安装私有的包
      • 创建新的Python环境
      • 分发包
    • 第十一章:网络与Web编程

    • 第十二章:并发编程

    • 第十三章:脚本编程与系统管理

    • 第十四章:测试、调试和异常

    • 第十五章:C语言扩展

  • Python基础

  • Python
  • 《Python Cookbook》第三版
  • 第十章:模块与包
weibw
2022-01-18

使用相对路径名导入包中子模块

# 问题

将代码组织成包,想用 import 语句从另一个包名没有硬编码过的包中导入子模块。

# 解决方案

使用包的相对导入,使一个模块导入同一个包的另一个模块 举个例子,假设在你的文件系统上有 mypackage 包,组织如下:

mypackage/
    __init__.py
    A/
        __init__.py
        spam.py
        grok.py
    B/
        __init__.py
        bar.py
1
2
3
4
5
6
7
8
9

如果模块 mypackage.A.spam 要导入同目录下的模块 grok,它应该包括的 import 语句如下:

# mypackage/A/spam.py
from . import grok
1
2

如果模块 mypackage.A.spam 要导入不同目录下的模块 B.bar,它应该使用的 import 语句如下:

# mypackage/A/spam.py
from ..B import bar
1
2

两个 import 语句都没包含顶层包名,而是使用了 spam.py 的相对路径。

# 讨论

在包内,既可以使用相对路径也可以使用绝对路径来导入。 举个例子:

# mypackage/A/spam.py
from mypackage.A import grok # OK
from . import grok # OK
import grok # Error (not found)
1
2
3
4

像 mypackage.A 这样使用绝对路径名的不利之处是这将顶层包名硬编码到你的源码中。如果你想重新组织它,你的代码将更脆,很难工作。 举个例子,如果你改变了包名,你就必须检查所有文件来修正源码。 同样,硬编码的名称会使移动代码变得困难。举个例子,也许有人想安装两个不同版本的软件包,只通过名称区分它们。 如果使用相对导入,那一切都 ok,然而使用绝对路径名很可能会出问题。

import 语句的 . 和 .. 看起来很滑稽, 但它指定目录名.为当前目录,..B 为目录../B。这种语法只适用于 import。 举个例子:

from . import grok # OK
import .grok # ERROR
1
2

尽管使用相对导入看起来像是浏览文件系统,但是不能到定义包的目录之外。也就是说,使用点的这种模式从不是包的目录中导入将会引发错误。

最后,相对导入只适用于在合适的包中的模块。尤其是在顶层的脚本的简单模块中,它们将不起作用。如果包的部分被作为脚本直接执行,那它们将不起作用 例如:

% python3 mypackage/A/spam.py # Relative imports fail
1

另一方面,如果你使用 Python 的-m 选项来执行先前的脚本,相对导入将会正确运行。 例如:

% python3 -m mypackage.A.spam # Relative imports work
1

更多的包的相对导入的背景知识,请看 PEP 328 (opens new window) .

编辑 (opens new window)
上次更新: 2023/10/13, 17:39:25
控制模块被全部导入的内容
将模块分割成多个文件

← 控制模块被全部导入的内容 将模块分割成多个文件→

最近更新
01
牛客网非技术快速入门SQL练习题
03-08
02
其他日常SQL题
03-07
03
用户与权限管理
03-05
更多文章>
Theme by Vdoing | Copyright © 2021-2023 | Weibw | 辽ICP备18015889号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式