第二十二章 模块:宏伟蓝图

模块是最高级别的程序组织单元,它将程序代码和数据封装起来以便在利用,同时提供自包含的命名空间从而避免程序出现变量名冲突。模块可以用下面两个语句和一个重要的内置函数进行处理:

  • import
    使用户程序(导入者)以一个整体获取一个模块;
  • from
    允许用户程序从一个模块文件中获取特定的名称;
  • imp.reload
    提供了一种在不终止python程序的情况下重新载入模块文件代码;

为什么使用模块

模块至少能扮演以下三个角色:

  • 代码重用
  • 系统命名空间的划分
  • 实现共享的服务数据

python程序架构

这种架构是将一个程序分割为源代码文件(也就是模块)的集合,并将这些集合连接成整体的方式。

如何组织一个程序

程序拥有一个主体的顶层文件,辅以零个或多个被称为模块的支持文件。

导入和属性

在这里插入图片描述
上图是一个包含三个文件的 Python 程序的草图:a.py,b.py和c.py。文件a.py是顶层文件,它是一个由语句组成的简单文本文件,在运行时这些语句将从上至下执行。文件b.py和c.py是模块,它们也是含有语句的简单文本文件,但是它们通常并不是直接运行。就像之前解释的那样,取而代之的是,模块通常被想要使用它们的文件导入。

# File b.py
def spam(text):
	print(text, 'spam')

如果a.py中想要使用spam。为了实现这个目标,可以使用以下语句:

# File a.py
import b
b.spam('gumby')

import 如何工作

程序在第一次导入指定文件时,会执行三个步骤:

  1. 找到模块文件;
  2. 编译成字节码(如果需要的话);
  3. 执行模块的代码来创建其所在定义的对象;

搜索

首先,python必须查找到import语句所引用的模块文件。上面我们在导入文件时,并没有.py的后缀,也没有文件路径。路径和后缀是刻意省略掉的,因为python使用了标准模块搜索路径来找出import语句所对应的模块文件。

编译(可选)

  • 编译
    如果发现字节码文件比源代码文件旧,或者是由不同的python版本编译的,就会在程序运行时自动重新生成字节码,字节码被集中存放在__pycache__子目录中;
  • 不编译
    另一方面,如果发现.pyc字节码文件不比对应的.py源代码文件旧,而且是由同一python版本所编译的,那么python就会跳过源代码到字节码的编译步骤;

运行

文件中所有语句会从头至尾依次执行,而此步骤中任何对名称的赋值运算,都会产生所得到的模块对象的属性。

字节码文件

__pycache __

字节码转而被存放在一个名为 pycache的子路径下。 Python在需要时会在存放源文件的路径下创建这个子路径。这能通过将字节码文件分离到它们独自的路径中,帮助我们避免文件路径中的拥挤。此外,尽管字节码文件像之前一样拥有.pyc扩展名,但它们拥有了更具描述性的文件名,新的文件名包含了生成该宇节码文件的 Python版本信息的文本(例如, module, cpython-32pyc)。这避免了不回版本间的竞争和重新编译:因为安装的每个 Python版本在 peache子路径下,都有它自己独特的字节码文件的命名,所以在一个版本下运行不会覆盖共他版本的字节码,从而也就节省了不必要的重新编译。事实上,字节码文件名也包括了生成它们的 Python的名字,因而CPython, Jython与其他在前言和第2章中提到的 Python实现可以在同一台机器上共存而不会互相影响对方的工作(只要它们支持这种模式)

模块搜索路径

模块搜索路径的先后:

  1. 程序的主目录;
  2. PYTHONPATH目录;
  3. 标准库目录;
  4. 任何.pth文件中的内容;
  5. 第三方扩展应用的site-packages主目录;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值