目录

一:概述

1.1标准模块

二:模块详解

2.1以脚本方式执行模块

6.1.2. 模块搜索路径

6.1.3. “已编译的” Python 文件

三:dir() 函数 和 包

3.1dir() 函数

3.2包 packages

3.3从包中导入 *

3.4子包参考

3.5多目录中的包


一:概述

退出后,再次进入 Python 解释器时,之前定义的函数和变量就丢失了。因此,编写较长程序时,建议用文本编辑器代替解释器,执行文件中的输入内容,这就是编写 脚本 。随着程序越来越长,为了方便维护,最好把脚本拆分成多个文件。编写脚本还一个好处,不同程序调用同一个函数时,不用每次把函数复制到各个程序。

为实现这些需求,Python 把各种定义存入一个文件,在脚本或解释器的交互式实例中使用。这个文件就是 模块 ;模块中的定义可以 导入 到其他模块或  模块(在顶层和计算器模式下,执行脚本中可访问的变量集)。

模块是包含 Python 定义和语句的文件。其文件名是模块名加后缀名 .py 。在模块内部,通过全局变量 __name__ 可以获取模块名(即字符串)。例如,用文本编辑器在当前目录下创建 fibo.py 文件,输入以下内容:

# Fibonacci numbers moduledef fib(n):    # write Fibonacci series up to na, b = 0, 1while a < n:print(a, end=' ')a, b = b, a+bprint()def fib2(n):   # return Fibonacci series up to nresult = []a, b = 0, 1while a < n:result.append(a)a, b = b, a+breturn result

如果经常使用某个函数,可以把它赋值给局部变量:

fib = fibo.fib
fib(500)

1.1标准模块

Python 附带了标准模块库,详见 Python 标准库参考手册 (以下简称为“库参考”)。解释器中内置了一些模块,用于访问不属于语言核心的内置操作,其目的主要是为了提高运行效率,或访问系统调用等操作系统原语。这些模块的集合是依赖于底层平台的配置选项。例如,winreg 模块仅供 Windows 使用。特别要注意内嵌到 Python 解释器中的模块 sys。变量 sys.ps1 和 sys.ps2 则用来定义主次提示的字符串:

>>> import sys
>>> sys.ps1
'>>> '
>>> sys.ps2
'... '
>>> sys.ps1 = 'C> '
C> print('Yuck!')
Yuck!
C>

只有解释器用于交互模式时,才定义这两个变量。

变量 sys.path 是字符串列表,用于确定解释器的模块搜索路径。该变量以环境变量 PYTHONPATH 提取的默认路径进行初始化,如未设置 PYTHONPATH,则使用内置的默认路径。可以用标准列表操作修改该变量:

import sys
sys.path.append('/ufs/guido/lib/python')

二:模块详解

模块包含可执行语句及函数定义。这些语句用于初始化模块,且仅在 import语句第一次遇到模块名时执行。[^1] (文件作为脚本运行时,也会执行这些语句。)

模块有自己的私有符号表,用作模块中所有函数的全局符号表。因此,在模块内使用全局变量时,不用担心与用户定义的全局变量发生冲突。另一方面,可以用与访问模块函数一样的标记法,访问模块的全局变量,modname.itemname

可以把其他模块导入模块。按惯例,所有 import 语句都放在模块(或脚本)开头,但这不是必须的。导入的模块名存在导入模块的全局符号表里。

  import 语句有一个变体,可以直接把模块里的名称导入到另一个模块的符号表。例如:

>>> from fibo import fib, fib2
>>> fib(500)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377

这段代码不会把模块名导入到局部符号表里(因此,本例没有定义 fibo)。

还有一种变体可以导入模块内定义的所有名称:

>>> from fibo import *
>>> fib(500)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377

这种方式会导入所有不以下划线(_)开头的名称。大多数情况下,不要用这个功能,这种方式向解释器导入了一批未知的名称,可能会覆盖已经定义的名称。

注意,一般情况下,不建议从模块或包内导入 *, 因为,这项操作经常让代码变得难以理解。不过,为了在交互式编译器中少打几个字,这么用也没问题。

模块名后使用 as 时,直接把 as 后的名称与导入模块绑定。

import fibo as fib
fib.fib(500)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377

与 import fibo 一样,这种方式也可以有效地导入模块,唯一的区别是,导入的名称是 fib

  from 中也可以使用这种方式,效果类似:

>>> from fibo import fib as fibonacci
>>> fibonacci(500)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377

注解:为了保证运行效率,每次解释器会话只导入一次模块。如果更改了模块内容,必须重启解释器;仅交互测试一个模块时,也可以使用 importlib.reload() ,例如 import importlib; importlib.reload(modulename)

2.1以脚本方式执行模块

可以用以下方式运行 Python 模块:

python fibo.py

这项操作将执行模块里的代码,和导入模块一样,但会把 __name__ 赋值为 "__main__"。 也就是把下列代码添加到模块末尾:

if __name__ == "__main__":import sysfib(int(sys.argv[1]))

既可以把这个文件当脚本使用,也可以用作导入的模块, 因为,解析命令行的代码只有在模块以 “main” 文件执行时才会运行:

$ python fibo.py 50
0 1 1 2 3 5 8 13 21 34

导入模块时,不运行这些代码:

>>> import fibo
>>>

这种操作常用于为模块提供便捷用户接口,或用于测试(把模块当作执行测试套件的脚本运行)。

6.1.2. 模块搜索路径

导入 spam 模块时,解释器首先查找名为 spam 的内置模块。如果没找到,解释器再从 sys.path 变量中的目录列表里查找 spam.py 文件。sys.path 初始化时包含以下位置:

  • 输入脚本的目录(或未指定文件时的当前目录)。
  • PYTHONPATH (目录列表,与 shell 变量 PATH 的语法一样)。
  • 默认安装目录。

注解

在支持 symlink 的文件系统中,输入脚本目录是在追加 symlink 后计算出来的。换句话说,包含 symlink 的目录并 没有 添加至模块搜索路径。

初始化后,Python 程序可以更改 sys.path。运行脚本的目录在标准库路径之前,置于搜索路径的开头。即,加载的是该目录里的脚本,而不是标准库的同名模块。 除非刻意替换,否则会报错。详见 标准模块。

6.1.3. “已编译的” Python 文件

为了快速加载模块,Python 把模块的编译版缓存在 __pycache__ 目录中,文件名为 module.*version*.pyc,version 对编译文件格式进行编码,一般是 Python 的版本号。例如,CPython 的 3.3 发行版中,spam.py 的编译版本缓存为 __pycache__/spam.cpython-33.pyc。使用这种命名惯例,可以让不同 Python 发行版及不同版本的已编译模块共存。

Python 对比编译版本与源码的修改日期,查看它是否已过期,是否要重新编译,此过程完全自动化。此外,编译模块与平台无关,因此,可在不同架构系统之间共享相同的支持库。

Python 在两种情况下不检查缓存。其一,从命令行直接载入模块,只重新编译,不存储编译结果;其二,没有源模块,就不会检查缓存。为了支持无源文件(仅编译)发行版本, 编译模块必须在源目录下,并且绝不能有源模块。

给专业人士的一些小建议:

  • 在 Python 命令中使用 -O 或 -OO 开关,可以减小编译模块的大小。-O 去除断言语句,-OO 去除断言语句和 doc 字符串。有些程序可能依赖于这些内容,因此,没有十足的把握,不要使用这两个选项。“优化过的”模块带有 opt- 标签,并且文件通常会一小些。将来的发行版或许会改进优化的效果。
  • 从 .pyc 文件读取的程序不比从 .py 读取的执行速度快,.pyc 文件只是加载速度更快。
  • compileall 模块可以为一个目录下的所有模块创建 .pyc 文件。
  • 本过程的细节及决策流程图,详见 PEP 3147

脚注

[^1] 实际上,函数定义也是“可执行”的“语句”;执行模块级函数定义时,函数名将被导入到模块的全局符号表。

三:dir() 函数 和 包

3.1dir() 函数

内置函数 dir() 用于查找模块定义的名称。返回结果是经过排序的字符串列表:

import fibo
dir(fibo)
# ['__name__', 'fib', 'fib2']

没有参数时,dir() 列出当前定义的名称

注意,该函数列出所有类型的名称:变量、模块、函数等。

dir() 不会列出内置函数和变量的名称。这些内容的定义在标准模块 builtins 里:

import builtins
dir(builtins)  

3.2包 packages

包是一种用“点式模块名”构造 Python 模块命名空间的方法。例如,模块名 A.B 表示包 A 中名为 B 的子模块。正如模块可以区分不同模块之间的全局变量名称一样,点式模块名可以区分 NumPy 或 Pillow 等不同多模块包之间的模块名称。

假设要为统一处理声音文件与声音数据设计一个模块集(“包”)。声音文件的格式很多(通常以扩展名来识别,例如:.wav, .aiff, .au),因此,为了不同文件格式之间的转换,需要创建和维护一个不断增长的模块集合。为了实现对声音数据的不同处理(例如,混声、添加回声、均衡器功能、创造人工立体声效果),还要编写无穷无尽的模块流。下图以分级文件系统形式展示这个包的架构:

sound/                          包(package)根目录__init__.py               初始化声音处理包formats/                  用于文件格式转换的子包装__init__.pywavread.pywavwrite.pyaiffread.pyaiffwrite.pyauread.pyauwrite.py...effects/                  声音效果的子包装__init__.pyecho.pysurround.pyreverse.py...filters/                  过滤器的子包装__init__.pyequalizer.pyvocoder.pykaraoke.py...

导入包时,Python 搜索 sys.path 里的目录,查找包的子目录。

Python 只把含 __init__.py 文件的目录当成包。这样可以防止以 string 等通用名称命名的目录,无意中屏蔽出现在后方模块搜索路径中的有效模块。 最简情况下,__init__.py 只是一个空文件,但该文件也可以执行包的初始化代码,或设置 __all__ 变量,详见下文。

还可以从包中导入单个模块,例如:

import sound.effects.echo

这段代码加载子模块 sound.effects.echo ,但引用时必须使用子模块的全名:

sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)

另一种导入子模块的方法是 :

from sound.effects import echo

这段代码还可以加载子模块 echo ,并且不加包前缀也可以使用。因此,可以按如下方式使用:

echo.echofilter(input, output, delay=0.7, atten=4)

另一种变体是直接导入所需的函数或变量:

from sound.effects.echo import echofilter

同样,这样也会加载子模块 echo,但可以直接使用函数 echofilter()

echofilter(input, output, delay=0.7, atten=4)

注意,使用 from package import item 时,item 可以是包的子模块(或子包),也可以是包中定义的函数、类或变量等其他名称。import 语句首先测试包中是否定义了 item;如果未在包中定义,则假定 item 是模块,并尝试加载。如果找不到 item,则触发 ImportError 异常。

相反,使用 import item.subitem.subsubitem 句法时,除最后一项外,每个 item 都必须是包;最后一项可以是模块或包,但不能是上一项中定义的类、函数或变量。

3.3从包中导入 *

使用 from sound.effects import * 时会发生什么?理想情况下,该语句在文件系统查找并导入包的所有子模块。这项操作花费的时间较长,并且导入子模块可能会产生不必要的副作用,这种副作用只有在显式导入子模块时才会发生。

唯一的解决方案是提供包的显式索引。import 语句使用如下惯例:如果包的 __init__.py 代码定义了列表 __all__,运行 from package import * 时,它就是用于导入的模块名列表。发布包的新版本时,包的作者应更新此列表。如果包的作者认为没有必要在包中执行导入 * 操作,也可以不提供此列表。例如,sound/effects/__init__.py 文件包含以下代码:

__all__ = ["echo", "surround", "reverse"]

即,from sound.effects import * 将导入 sound 包中的这三个命名子模块。

如果没有定义 __all__from sound.effects import * 语句 不会 把包 sound.effects 中所有子模块都导入到当前命名空间;该语句只确保导入包 sound.effects (可能还会运行 __init__.py 中的初始化代码),然后,再导入包中定义的名称。这些名称包括 __init__.py 中定义的任何名称(以及显式加载的子模块),还包括之前 import 语句显式加载的包里的子模块。请看以下代码:

import sound.effects.echo
import sound.effects.surround
from sound.effects import *

本例中,执行 from...import 语句时,将把 echo 和 surround 模块导入至当前命名空间,因为,它们是在 sound.effects 包里定义的。(该导入操作在定义了 __all__ 时也有效。)

虽然,可以把模块设计为用 import * 时只导出遵循指定模式的名称,但仍不提倡在生产代码中使用这种做法。

记住,使用 from package import specific_submodule 没有任何问题! 实际上,除了导入模块使用不同包的同名子模块之外,这种方式是推荐用法。

3.4子包参考

包中含有多个子包时(与示例中的 sound 包一样),可以使用绝对导入引用兄弟包中的子模块。例如,要在模块 sound.filters.vocoder 中使用 sound.effects 包的 echo 模块时,可以用 from sound.effects import echo 导入。

还可以用 import 语句的 from module import name 形式执行相对导入。这些导入语句使用前导句点表示相对导入中的当前包和父包。例如,相对于 surround 模块,可以使用:

from . import echo
from .. import formats
from ..filters import equalizer

注意,相对导入基于当前模块名。因为主模块名是 "__main__" ,所以 Python 程序的主模块必须始终使用绝对导入。

3.5多目录中的包

包还支持特殊属性 path ,该属性初始化为在包的 init.py 文件中的代码执行前所在的目录名列表。这个变量可以修改,但这样做会影响将来搜索包中模块和子包的操作。

这个功能虽然不常用,但可用于扩展包中的模块集。

学习Python编程基础学习笔记(5.模块和包)相关推荐

  1. 软件测试Python编程基础学习分享

    #博学谷IT学习技术支持# 目录 一.前言 二.python基础 2.1print函数的简单使用 2.2注释 2.2.1单行注释 2.2.2多行注释 2.3Python代码中三种波浪线和 PEP8 2 ...

  2. 1 python编程基础学习

    1 python编程基础学习 1. 程序 2 python简介(了解) 3 python的开发环境的搭建 4 第一个python程序 4.1 常用的dos命令 4.2 交互式 4.3 使用pychar ...

  3. 自学python入门-自学Python编程基础学习笔记 PDF 完整超清版

    一. Why. 为什么学习Python.Python这门语言​用处比较广泛: 1.写测试脚本,因为PY是解释性语言,天生就有作为测试脚本语言的优势,语法简单,通俗易懂,可移植性好(底层使用C语言来编写 ...

  4. Datawhale组队学习-Python编程基础-07

    文章目录 类与对象 1.对象 = 属性 + 方法 2.self是什么? 3.Python的魔法方法 4.共有和私有 5.继承 6.组合 7.类.类对象和实例对象 8.什么是绑定? 9.一些相关的内置函 ...

  5. Datawhale组队学习-Python编程基础-01

    文章目录 变量.运算符与数据类型 1.注释 2.运算符 3.变量和赋值 4.数据类型与转换 5.print()函数 练习题 位运算 1.原码.反码和补码 2.按位非操作~ 3.按位与操作& 4 ...

  6. Python编程基础:第六节 math包的基础使用Math Functions

    第六节 math包的基础使用 前言 实践 前言 我们通常会对数值型变量进行计算,这里我们给出一些常用的函数用于辅助你的计算过程.常用的数学计算函数均在math包. 实践 首先我们导入math包,并定义 ...

  7. python语言好不好_《python编程基础》这本书怎么样

    <python编程基础>这本书怎么样 发布时间:2020-11-11 12:01:06 来源:亿速云 阅读:73 作者:小新 小编给大家分享一下<python编程基础>这本书怎 ...

  8. python编程零基础免费网课-Python网课推荐——免费学习Python编程

    对于想要学习python的初学者,面对网上大量的学习素材无从下手.今天小编就整理了一份详细的python教学视频合集,希望能为初学者提供一些学习的方向. 1.python入门 课程推荐:零基础入门学习 ...

  9. python编程基础的阅读心得体会_学习Python的一些心得体会(熊逸飞)

    PART 2 第一章作者没有抛出过多内容,只是简单介绍了Python作为编程语言的一些比较优势,然后介绍它的历史和创始人的故事.从90年首次发布到现在经历了十几次优化才有了如今我们使用的Python, ...

最新文章

  1. 面向隐私AI的TensorFlow深度定制化实践
  2. 他花了一个月,使用MicroPython将自己装进OLED里面
  3. python包pip安装_python包管理之Pip安装及使用
  4. 消息队列mysql redis那个好_Redis作为消息队列与RabbitMQ的比较
  5. Brocade 光纤交换机常用命令
  6. html 定位z_index,绝对定位、固定定位和z-index
  7. 本人原创,如何应用firebug突破新浪ishare下载限制
  8. dijkstra算法学习笔记
  9. 点击开始十秒倒计时html,十秒倒计时案例.html
  10. 服务器怎么不用绑定域名搭建网站,一个空间放两个网站,且不用子目录绑定域名的方法...
  11. 以大数据架构电商2.0的新时代
  12. 表格内容如何合并在一起
  13. html新浪短域名api,新浪(t.cn)短网址API-API文档-免费api接口-短网址工具
  14. LeetCode 古生物血缘远近判定 ( dp )
  15. 苹果手机10秒解除锁屏_苹果密码忘了不想刷机怎么办_苹果手机10秒解除锁屏
  16. 用python动态时钟代码_python实现简易动态时钟
  17. ibatis之——sqlMapConfig.xml配置文件详解
  18. php 五子棋对战,五林大会五子棋
  19. 怎样快速上手PPT制作?
  20. 模拟电路65(串联型稳压电路1)

热门文章

  1. 所有白手起家的百万富翁都有他们能成功的原因
  2. 【eNSP 华为模拟器】小型校园网模拟环境的设计与配置(附eNSP源文件)
  3. [译]JavaScript:更严格的相等
  4. 乐意微信HOOK培训教程(易语言版)价值1500元
  5. 揭开脚本的神秘面纱!【JavaScript】初识!
  6. python扫雷_【Python】扫雷小游戏(PyQt5)
  7. 我想给日历软件增加读取outlook日历功能
  8. 传智黑马武汉校区学生总结 史上最强500G JAVA全套视频教程网盘
  9. day6 面向对象
  10. PHP Tcpdf 生成 pdf 并将 (Imagick) pdf 生成 图片