Python教程-模块
本系列为作者在官网学习python时做的笔记,详见python官网
python标准库官方文档,查阅标准库相关的内容
python语言参考,查看python语法,该文档是简洁的,但试图做到准确和完整。非必要的内建对象类型和内建函数、模块的语义描述在 Python 标准库 中。
标准库和语言参考涵盖了python的所有内容,他们是互补的,如果在语言参考中没有找到需要的内容那么就一定在便准库文档中。
更多有关模块的信息
模块可以包含可执行的语句以及函数定义。这些语句用于初始化模块。它们仅在模块 第一次 在 import 语句中被导入时才执行。(当文件被当作脚本运行时(模块的__name__
属性为main
),它们也会执行。)
每个模块都有它自己的私有符号表,不必担心模块内全局变量与用户的全局变量发生意外冲突。另一方面,可以用跟访问模块内的函数的同样标记方法,去访问一个模块的全局变量,modname.itemname。
可以把其他模块导入模块。被导入的模块名存在导入方模块的全局符号表里。
可以把名字从一个被调模块内直接导入到现模块的符号表里。例如:
|
|
这并不会把被调模块名引入到局部变量表里(因此在这个例子里,fibo 是未被定义的)。
还可以导入模块内定义的所有名称:
|
|
这会调入所有非以下划线(_)开头的名称。不推荐使用,有覆盖你本地变量的风险。在交互式编译器中为了节省打字可以这么用。
如果模块名称之后带有 as,则跟在 as 之后的名称将直接绑定到所导入的模块(原来的模块名不会被导入)。
|
|
这种方式也可以在用到 from 的时候使用:
|
|
每个模块在每个解释器会话中只被导入一次。如果你更改了你的模块,则必须重新启动解释器。如果它只是一个要交互式地测试的模块,可以使用 importlib.reload()
|
|
以脚本的方式执行模块
当你用下面方式运行一个Python模块:
|
|
这项操作将执行模块里的代码,而且会把 __name__
赋值为 "__main__"
。 也就是会运行下面的代码:
|
|
如果模块是被导入的,那些代码是不运行的:
|
|
模块搜索路径
当一个名为 spam 的模块被导入的时候,解释器首先寻找具有该名称的内置模块。如果没有找到,然后解释器从 sys.path 变量给出的目录列表里寻找名为 spam.py 的文件。sys.path 初始有这些目录地址:
- 包含输入脚本的目录(或者未指定文件时的当前目录)。
- PYTHONPATH (一个包含目录名称的列表,它和shell变量 PATH 有一样的语法)。
- 取决于安装的默认设置
在初始化后,Python程序可以更改 sys.path。除非有意更换,否则这是错误。
“编译过的”Python文件
为了加速模块载入,Python在 ${PYTHON_HOME}/Lib/__pycache__
目录里缓存了每个模块的编译后版本,名称为 module.version.pyc
,其中名称中的版本字段对编译文件的格式进行编码; 它一般使用Python版本号。如telnetlib.cpython-38.pyc
Python根据编译版本检查源的修改日期,以查看它是否已过期并需要重新编译。这是一个完全自动化的过程。
编译的模块与平台无关,因此可以在具有不同体系结构的系统之间共享相同的库。
Python在两种情况下不会检查缓存而是直接编译:
- 从命令行直接载入的模块
- 没有源模块
给专业人士的一些小建议:
- 你可以在Python命令中使用 -O 或者 -OO 开关, 以减小编译后模块的大小。 -O 开关去除断言语句,-OO 开关同时去除断言语句和 doc 字符串。
- 一个从 .pyc 文件读出的程序并不会比它从 .py 读出时运行的更快,.pyc 文件唯一快的地方在于载入速度。
- compileall 模块可以为一个目录下的所有模块创建.pyc文件。
标准模块
一些模块内置于解释器中;它们提供对不属于语言核心但仍然内置的操作的访问,以提高效率或提供对系统调用等操作系统原语的访问。这些模块的集合是一个配置选项,它也取决于底层平台。例如,winreg 模块只在Windows操作系统上提供。一个特别值得注意的模块 sys,它被内嵌到每一个Python解释器中。变量 sys.ps1 和 sys.ps2 定义用作主要和辅助提示的字符串:
|
|
这两个变量只有在编译器是交互模式下才被定义。
sys.path 变量是一个字符串列表,用于确定解释器的模块搜索路径。该变量被初始化为从环境变量 PYTHONPATH 获取的默认路径,或者如果 PYTHONPATH 未设置,则从内置默认路径初始化。可以使用标准列表操作对其进行修改:
|
|
dir() 函数
内置函数 dir() 用于查找模块定义的名称。 它返回一个排序过的字符串列表:
|
|
如果没有参数,dir() 会列出你当前定义的名称:
|
|
注意:它列出所有类型的名称:变量,模块,函数,等等。
dir() 不会列出内置函数和变量的名称。如果你想要这些,它们的定义是在标准模块 builtins 中:
|
|
包
包是目录,模块是py文件
包是一种通过用“带点号的模块名”来构造 Python 模块命名空间的方法。
必须要有 __init__.py
文件才能让 Python 将包含该文件的目录当作包。 在最简单的情况下,__init__.py
可以只是一个空文件,但它也可以执行包的初始化代码或设置 __all__
变量,
包的用户可以从包中导入单个模块,例如:
|
|
这会加载子模块 sound.effects.echo ,但引用它时必须使用它的全名。
|
|
导入子模块的另一种方法是
|
|
这也会加载子模块 echo ,并使其在没有包前缀的情况下可用:
|
|
另一种形式是直接导入所需的函数或变量:
|
|
同样,这也会加载子模块 echo,但函数 echofilter() 直接可用:
|
|
请注意,当使用 from package import item
时,item可以是包的子模块(或子包),也可以是包中定义的其他名称,如函数,类或变量。 import 语句首先测试是否在包中定义了item;如果没有,它假定它是一个模块并尝试加载它。如果找不到它,则引发 ImportError 异常。
相反,当使用 import item.subitem.subsubitem
最后一项不能是前一项中定义的类或函数或变量。
从包中导入 *
from sound.effects import *
找到包中存在哪些子模块,并将它们全部导入。这可能需要很长时间。
如果一个包的 __init__.py
代码定义的名为 __all__
的列表会被视为在遇到 from package import *
时应该导入的模块名列表。例如,文件 sound/effects/__init__.py
可以包含以下代码:
|
|
这意味着 from sound.effects import *
将导入 sound 包的三个命名子模块。
如果没有定义 __all__
,from sound.effects import *
语句 不会 从包 sound.effects 中导入所有子模块到当前命名空间;它只确保导入了包 sound.effects 任何在__init__.py
中的初始化代码定义的任何名称。 这包括 __init__.py
定义的任何名称(以及显式加载的子模块):
子包参考
当包被构造成子包时(与示例中的 sound 包一样),你可以使用绝对导入(相对项目目录而言)来引用兄弟包的子模块。例如,如果模块 sound.filters.vocoder 需要在 sound.effects 包中使用 echo 模块,它可以使用 from sound.effects import echo 。
你还可以使用import语句的 from module import name 形式编写相对导入。这些导入使用前导点来指示相对导入中涉及的当前包和父包。例如,从 surround 模块,你可以使用:
|
|
推荐使用绝对导入
多个目录中的包
包支持另一个特殊属性, __path__
。它被初始化为一个列表,其中包含在执行该文件中的代码之前保存包的文件 __init__.py
的目录的名称。这个变量可以修改;这样做会影响将来对包中包含的模块和子包的搜索。
虽然通常不需要此功能,但它可用于扩展程序包中的模块集。
还是很重要的,在服务器上很好使用
腾讯云开发者社区 静谧星空TEL python引入相同和不同(模块)文件夹下py文件的类
|
|
多次import一个模块
多次import一个模块只会执行一次