定义:
模块是包含 Python 定义和语句的文件。其文件名是模块名加后缀名 .py 。在模块内部,通过全局变量 __name__ 可以获取模块名(即字符串)。
导入模块:
| |
本质将模块名称添加到namespeac而非把定义的函数添加进去
6.1 模块详解:
模块包含可执行语句及函数定义。这些语句用于初始化模块,且仅在 import 语句 第一次 遇到模块名时执行。
每个模块都有它自己的私有符号表,该表被定义在该模块里的所有函数当作全局符号表使用。
您可以使用与引用模块函数相同的语法去访问一个模块的全局变量,即 modname.itemname
导入其他模块:import
被放置于一个模块的最高层级,则被导入的模块名称会被添加到该模块的全局命名空间。 import的变式1:将来自某个模块的名称直接导入到导入方的命名空间里面
| |
变式2:导入模块内定义的所有名称(不包含以_开头的名称)
| |
不建议:可能会覆盖已经定义的名称
变式3:模块名后接as
| |
或者变式1,3结合
| |
备注
每次解释器会话只导入一次模块,若模块内容更改,需要重启解释器
如仅交互测试一个模块,可以使用importlib.reload(),例如 import importlib; importlib.reload(modulename)。
6.1.1.以脚本方式执行模块
最常见命令:
| |
导入模块的代码,但是会将_name_命名为"main"(这里前面和后面都有一个__,但是因为md原因导致没有了)
例如
| |
相当于
| |
该文件既可作为模块又可以作为脚本 而像下面这种导入其他模块则不会
| |
用于为模块提供一个便捷的用户接口,或用于测试
6.1.2.模块的搜索路径
当导入一个名为 spam 的模块时,解释器首先会搜索具有该名称的内置模块。 这些模块的名称在 sys.builtin_module_names 中列出。 如果未找到,它将在变量 sys.path 所给出的目录列表中搜索名为 spam.py 的文件。 sys.path 是从这些位置初始化的:
- 被命令行直接运行的脚本所在的目录(或未指定文件时的当前目录)。
PYTHONPATH(目录列表,与 shell 变量PATH的语法一样)。- 依赖于安装的默认值(按照惯例包括一个
site-packages目录,由site模块处理)。
更多细节请参阅 sys.path 模块搜索路径的初始化。
备注
在支持符号链接的文件系统中,“被命令行直接运行的脚本所在的目录”是符号链接最终指向的目录。换句话说,符号链接所在的目录并 没有 被添加至模块搜索路径。
初始化后,Python 程序可以更改 sys.path。脚本所在的目录先于标准库所在的路径被搜索。这意味着,脚本所在的目录如果有和标准库同名的文件,那么加载的是该目录里的,而不是标准库的。这一般是一个错误,除非这样的替换是你有意为之。详见 标准模块。
6.1.3.”已编译的“Python文件
模块的编译版本存放在–pycache__目录中,文件名为module.version.pyc,
version:对编译文件格式进行编码,一般是版本号
可以让不同版本的Python编译的模块可以共存
例子:CPython 的 3.3 发行版中,spam.py 的编译版本缓存为 __pycache__/spam.cpython-33.pyc
Python会自动检查编译版本和源码的修改日期来查看编译版是否过期,是否需要重新编译 编译模块与平台无关 Python不检查缓存的两种情况 1.从命令行直接载入的模块:每次重新编译且不存储结果 2.没有源模块 隐藏源代码:将所有源代码编程编译之后的版本,并储存在源目录而非缓存目录中)
ps:
.pyc的读取未必比.py快,只是加载速度更快
compileall 模块可以为一个目录下的所有模块创建 .pyc 文件。
6.2.标准模块
Python自带的,在Python的库参考中另外描述 这些模块集是一个配置选项,并且还依赖于底层的操作系统 例如winreg只在WIndows系统上提供 但是sys模块内嵌到每一个Python解释器,sys.psq和sys.ps2变量定义了一些字符,可以作为主提示符和辅助提示符 变量的sys.path:字符串列表,用于确定解释器的模块搜索路径 从环境变量PYTHONPATH提取默认路径进行初始化,若未设置PYTHONPATH,则使用内置的默认路径 可以通过标准列表操作修改该变量
| |
6.3.dir()函数
查找模块定义的名称,返回值:经过排序的字符串列表
没有参数时:
返回值:当前已经定义的名称
包括:变量,模块,函数……
但是不会列出内置函数和变量的名称
这些内容的定义在标准模块 builtins 中:
6.4. 包
通过”带点号模块名“来狗仔Python模块命名空间的一种方式 可以让不同包的作者不用担心彼此的全局变量名,比如模块名冲突
导入包时,Python 搜索 sys.path 里的目录,查找包的子目录。
需要有 __init__.py 文件才能让 Python 将包含该文件的目录当作包来处理(除非使用 namespace package,这是一个相对高级的特性)。 这可以防止重名的目录如 string 在无意中屏蔽后继出现在模块搜索路径中的有效模块。 在最简单的情况下,__init__.py 可以只是一个空文件,但它也可以执行包的初始化代码或设置 __all__ 变量,这将在稍后详细描述。
还可以从包中导入单个模块,例如:
| |
这将加载子模块 sound.effects.echo。 它必须通过其全名来引用。
| |
另一种导入子模块的方法是 :
| |
这也会加载子模块 echo,并使其不必加包前缀,因此可按如下方式使用:
| |
Import 语句的另一种变体是直接导入所需的函数或变量:
| |
同样,这将加载子模块 echo,但这使其函数 echofilter() 直接可用:
| |
注意,使用 from package import item 时,item 可以是包的子模块(或子包),也可以是包中定义的函数、类或变量等其他名称。import 语句首先测试包中是否定义了 item;如果未在包中定义,则假定 item 是模块,并尝试加载。如果找不到 item,则触发 ImportError 异常。
相反,使用 import item.subitem.subsubitem 句法时,除最后一项外,每个 item 都必须是包;最后一项可以是模块或包,但不能是上一项中定义的类、函数或变量。
6.4.1. 从包中导入*
提供包的显式索引
导入在init.py 代码定义了列表 all
发布新版本时,应更新该列表
例如:sound/effects/__init__.py 文件可以包含以下代码:
| |
这意味着 from sound.effects import * 将导入 sound.effects 包的三个命名子模块。请注意子模块可能会受到本地定义名称的影响。 例如,如果你在 sound/effects/__init__.py 文件中添加了一个 reverse 函数,from sound.effects import * 将只导入 echo 和 surround 这两个子模块,但 不会 导入 reverse 子模块,因为它被本地定义的 reverse 函数所遮挡:
| |
没有定义____all____:
有点没懂
6.4.2. 相对导入
使用前导符号.来完成 一般用于子模块