飞翔飞翔
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
  • 数据库

    • SQL教程
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON教程
  • 工具

    • Markdown指南
  • Git

    • GitFlow
  • Quartz

    • Quartz教程
  • Java

    • Java设计模式
  • 缓存

    • Redis教程
联系
阿里云
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
  • 数据库

    • SQL教程
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON教程
  • 工具

    • Markdown指南
  • Git

    • GitFlow
  • Quartz

    • Quartz教程
  • Java

    • Java设计模式
  • 缓存

    • Redis教程
联系
阿里云
  • 学习路径
  • 第1章 认识Python

    • Python 历史与特点
    • Python 2 与 Python 3 的核心差异
    • 安装与运行 Python 2.7.18
    • 编码规范 PEP 8
  • 第2章 基础语法

    • 变量与对象
    • 数字类型
    • 字符串 str
    • Unicode 字符串
    • 运算符
    • 空值 None
  • 第3章 流程控制

    • if 条件语句
    • if-else 条件语句
    • if-elif-else 多分支
    • 条件表达式(三元运算符)
    • while 循环
    • for 循环
    • range 与 xrange
    • 循环控制:break、continue、pass
    • 循环 else 子句
  • 第4章 数据结构

    • 列表基础
    • 列表方法
    • 列表推导式
    • 元组
    • 字典基础
    • 字典方法
    • 字典循环技巧
    • 集合
    • 序列解包
    • 序列比较
  • 第5章 函数

    • 定义函数
    • 参数传递机制
    • 默认参数
    • 关键字参数
    • 可变参数
    • Lambda 表达式
    • 文档字符串
    • 函数对象
  • 第6章 模块与包

    • import 导入
    • 模块搜索路径
    • name 与主程序
    • 编译文件 .pyc 与 .pyo
    • 包结构
    • dir() 函数
  • 第7章 文件与IO

    • 打开与关闭文件
    • 文件读写方法
    • with 上下文管理器
    • 格式化输出:% 操作符
    • 格式化输出:str.format()
    • JSON 序列化
  • 第8章 面向对象

    • 类定义与实例化
    • init 构造方法
    • 类变量与实例变量
    • 方法调用与 self
    • 继承基础
    • 多重继承
    • 新式类与旧式类
    • 私有变量与名称改写
    • 属性装饰器 property
    • 类方法与静态方法
    • 魔术方法
    • 空类与数据记录
  • 第9章 异常处理

    • 异常类型
    • try-except
    • try-except-else-finally
    • 抛出异常 raise
    • 自定义异常
    • with 语句与上下文管理器
  • 第10章 迭代器与生成器

    • 迭代器协议
    • 生成器函数
    • 生成器表达式
    • itertools模块
  • 第11章 标准库精要

    • os模块
    • sys模块
    • datetime模块
    • re模块
    • json模块
    • collections模块
    • math与random模块
    • urllib2与网络请求
    • subprocess与命令执行
    • threading与并发
    • unittest与测试
    • 虚拟环境与包管理
  • 第12章 工程实践

    • 调试技巧
    • 性能分析
    • 文档与注释
    • 下一步学习

import 导入

模块是 Python 组织代码的基本单元。一个 .py 文件就是一个模块,模块名就是文件名(不含 .py 后缀)。import 语句让当前程序可以使用其他模块中定义的函数、类和变量。

基本导入

import math

print math.pi           # 3.14159265359
print math.sqrt(16)    # 4.0

import math 导入整个 math 模块。使用时必须通过 math.name 访问模块中的内容。这种写法清晰明了:读者一眼就能看出 pi 和 sqrt 来自 math 模块。

从模块导入指定名称

from math import pi, sqrt

print pi                # 3.14159265359
print sqrt(16)          # 4.0

from math import pi, sqrt 只导入 pi 和 sqrt 两个名字,可以直接使用,无需前缀。适合频繁使用的名称,但牺牲了可读性——读者可能不知道 sqrt 来自哪里。

导入所有公开名称

from math import *

print pi
print sqrt(16)
print sin(0)

from module import * 导入模块中所有不以下划线开头的名称。这种写法方便但危险:

from os import *        # 导入了 os.open
from math import *      # 没有 open

open("file.txt")        # 用的是 os.open 还是内置 open?

os.open 和内置 open 参数完全不同,混用会导致难以调试的 bug。PEP 8 明确反对 import *,除非在交互式解释器中快速试验。

别名导入

import numpy as np
from math import pi as PI

print np.array([1, 2, 3])
print PI

as 给导入的模块或名称起别名。这在以下场景很有用:

  • 模块名太长(numpy → np)
  • 避免名称冲突(math.pi → PI)
  • 统一接口(不同平台导入不同实现,但用相同别名)

导入的执行过程

import 第一次导入模块时,会执行模块文件的全部代码:

# mymodule.py
print "Loading mymodule"

def hello():
    print "Hello from mymodule"

# main.py
import mymodule     # 输出:Loading mymodule
import mymodule     # 无输出,已缓存

第二次 import mymodule 不会重新执行,而是从 sys.modules 缓存中直接获取已加载的模块对象。如果需要重新加载(如调试时修改了模块文件),用 reload():

import mymodule
reload(mymodule)    # 重新执行模块代码

⚠️ reload() 是 Python 2 的内置函数,Python 3 中移到了 importlib 模块。

导入的搜索路径

Python 按以下顺序查找模块:

  1. 当前目录
  2. PYTHONPATH 环境变量中的目录
  3. 标准库目录
  4. 第三方包目录(site-packages)
import sys
print sys.path        # 查看搜索路径列表

sys.path 是一个列表,可以在运行时修改:

import sys
sys.path.insert(0, "/path/to/my/modules")
import mymodule

循环导入

两个模块互相导入会形成循环导入,可能导致问题:

# a.py
import b

def func_a():
    b.func_b()

# b.py
import a

def func_b():
    print "func_b"

当 a.py 被导入时,它开始执行 import b,b.py 开始执行 import a。此时 a 模块尚未完全初始化,b 中访问 a 的内容可能得到不完整的模块对象。

解决方法:

  1. 重构代码,消除循环依赖
  2. 把导入语句放到函数内部,延迟导入
  3. 合并两个模块
# b.py —— 延迟导入
def func_b():
    import a          # 在函数内部导入
    a.func_a()

导入的命名空间

import 语句在当前命名空间中创建名称:

import math           # 创建名称 "math",指向 math 模块
from math import pi   # 创建名称 "pi",指向 math.pi

导入的名称可以像普通变量一样使用:

import math
alias = math          # alias 也指向 math 模块
print alias.pi        # 3.14159265359

del math              # 删除名称 "math",但模块仍在内存中
print alias.pi        # 仍然可以访问
下一页
模块搜索路径