Python 简单入门指北
  • Introduction
  • 1.1 数组
    • 1.1.1 列表推导
    • 1.1.2 元组
    • 1.1.3 数组切片
    • 1.1.4 循环与遍历
    • 1.1.5 魔术方法
  • 1.2 字典
    • 1.2.1 初始化字典
    • 1.2.2 查询字典
    • 1.2.3 遍历字典
    • 1.2.4 字典的魔术方法
    • 1.2.5 集合
  • 1.3 字符串
    • 1.3.1 字符串编码
    • 1.3.2 字符串的常用方法
    • 1.3.3 字符串格式化
    • 1.3.4 HereDoc
  • 2.1 函数是一等公民
    • 2.1 函数是一等公民
  • 2.2 函数参数
    • 2.2.1 函数传参
    • 2.2.2 默认参数
    • 2.2.3 多参数传递
    • 2.2.4 参数分类
  • 2.3 函数内省
    • 2.3 函数内省
  • 2.4 参数分类
    • 2.4.1 设计模式的消亡
    • 2.4.2 装饰器的基本原理
    • 2.4.3 装饰器进阶
    • 2.4.4 装饰器工厂
  • 3.1 对象内存管理
    • 3.1.1 对象不是盒子
    • 3.1.2 默认浅复制
    • 3.1.3 弱引用
  • 3.2 Python 风格的对象
    • 3.2.1 静态函数与类方法
    • 3.2.2 属性 attribute
    • 3.2.3 特性 property
    • 3.2.4 特性工厂
    • 3.2.5 属性描述符
    • 3.2.6 实例属性的查找顺序
  • 3.3 多继承
    • 3.3.1 多继承的必要性
    • 3.3.2 Python 的多继承
    • 3.3.3 Mixin
    • 3.3.4 抽象类
  • 3.4 元编程
    • 3.4.1 类工厂函数
    • 3.4.2 元类的概念
    • 3.4.3 元类的使用示例
  • 4.1 else
    • 4.1.1 for else
    • 4.1.2 while else
    • 4.1.3 try else
  • 4.2 迭代器
    • 4.2.1 迭代器
    • 4.2.2 可迭代对象
    • 4.2.3 iter 方法
    • 4.2.4 标准迭代器
    • 4.2.5 初始生成器
  • 4.3 生成器
    • 4.3.1 生成器的定义
    • 4.3.2 生成器表达式
    • 4.3.3 协程
    • 4.3.4 预激协程
    • 4.3.5 标准库中的生成器函数
  • 4.4 上下文管理器
    • 4.4.1 with 块
    • 4.4.2 自定义上下文
    • 4.4.3 标准库中的上下文
  • 5.1 多线程与 GIL
    • 5.1.1 多线程
    • 5.1.2 线程锁
    • 5.1.3 GIL
    • 5.1.4 多进程
  • 5.2 我眼中的 Python
    • 5.2.1 Python 是动态强类型语言
    • 5.2.2 开发效率高
    • 5.2.3 对新人不是很友好
  • 5.3 其他 Python 技巧
    • 5.3.1 文件读写
    • 5.3.2 JSON 读写
    • 5.3.3 执行 Shell
  • 5.4 Python 模块化
    • 5.4.1 Python 中的模块化
    • 5.4.2 模块查找顺序
    • 5.4.3 包与 init.py
    • 5.4.4 相对导入和绝对导入
    • 5.4.5 运行 Python 脚本
  • 5.5 venv
    • 5.5.1 什么是 venv
    • 5.5.2 venv 结构初探
    • 5.5.3 工作原理
  • 6. 学习方向
    • 6. 学习方向
  • 7。参考资料
    • 7. 参考资料
Powered by GitBook
On this page
  1. 5.4 Python 模块化

5.4.2 模块查找顺序

对于被 import 的模块,Python 首先会检查它是不是内置的模块,比如我们把刚刚的 module.py 文件重命名为 time.py,再引用:

import time
time.add(1, 2)
# 报错:AttributeError: module 'time' has no attribute 'add'

这是因为 Python 最先查找内置的模块,我们打印 time 模块就可以看到 <module 'time' (built-in)> ,说明这是一个内置模块。PS:string 模块不是内置模块,坑了我一晚上。

如果导入的不是内置模块,Python 会依次在 sys.path 这个数组中的每个路径中寻找。按照查找优先级,它由三个部分组成:

  1. Python 执行的入口文件(比如这里的 main.py)所在的路径

  2. 系统的环境变量 $PYTHONPATH 所表示的目录

  3. site 路径,也就是 /usr/local/lib/python3.5/site-packages 这种。

如果我们把 time.py 改名为 string.py 就会得到正常结果,这是因为它属于第一部分,而 Python 默认的 string 模块位于第三部分,优先级比较低。

一般来说,Python 工程中的文件都能在第一部分被找到,而 pip安装的第三方库位于第三部分。环境变量 PYTHONPATH 一般都是空,但不排除某些 IDE,比如 PyCharm 会修改它。这种行为很危险,因为能在 PyCharm 中编译通过很可能是借助环境变量才找到了模块,一旦迁移到别的环境就无法编译,我似乎遇到过这个坑,将本地可以运行的代码上传到 VPS 以后就找不到模块了。

Previous5.4.1 Python 中的模块化Next5.4.3 包与 init.py

Last updated 6 years ago