python module docs_27 python-docs 6.模块

# -*- coding:utf-8 -*-

#yys

import sys

print(sys.version)#3.6.7 |Anaconda, Inc.| (default, Oct 28 2018, 19:44:12) [MSC v.1915 64 bit (AMD64)]

import platform

print(platform.architecture()) #('64bit', 'WindowsPE')

print(platform.platform()) #Windows-10-10.0.14393-SP0

print(platform.system()) #Windows

print()

#######

#使用文本编辑器为解释器准备输入并将该文件作为输入运行。这被称作编写 脚本。

# Python 有一种方法可以把定义放在一个文件里,并在脚本或(解释器的交互式实例)中使用它们。这样的文件被称作 模块;

# 模块是一个包含 Python 定义和语句的文件。文件名就是模块名后跟文件后缀 .py 。

# 在一个模块内部,模块名(作为一个字符串)可以通过全局变量 __name__ 的值获得。

print(__name__ ) #__main__

print("*"*30)

# 每个模块都有它自己的私有符号表,该表用作模块中定义的所有函数的全局符号表。

# 去访问一个模块的全局变量,可以用modname.itemname。

# 被导入的模块名存放在调入模块的全局符号表中。

# import 语句有一个变体,它可以把名字从一个被调模块内直接导入到现模块的符号表里。

# 例如:

# from fibo import fib, fib2 ( fibo是模块名,fib, fib2是模块内定义的函数名称)

# 这并不会把被调模块名引入到局部变量表里(因此在这个例子里,fibo 是未被定义的)。

# 还有一个变体甚至可以导入模块内定义的所有名称:

# 不建议使用:从一个模块或者包内调入 * 的做法是不太被接受的,因为这通常会导致代码的可读性很差。

# from fibo import *

# 这会调入所有非以下划线(_)开头的名称。在多数情况下,Python 程序员都不会使用这个功能,因为它在

# 解释器中引入了一组未知的名称,而它们很可能会覆盖一些你已经定义过的东西。

# 如果模块名称之后带有 as,则跟在 as 之后的名称将直接绑定到所导入的模块。(相当于重命名)

# import fibo as fib

# 注意:出于效率的考虑,每个模块在每个解释器会话中只被导入一次。因此导入的包很多,解释器加载可能慢一点,加载后的运行并不一定慢。

# 关于模块内的全局变量 __name__ 变量

# 当在当前模块内引用全局变量: __name__时,__name__为 " _main__" ;

# 当模块被其他模块引用时,__name__的值是模块的名称;

'''if __name__ == "__main__":print()print('当前的__name__全局变量名称为"__main__"')print()print("#"*30)import debug as bugprint(bug.__name__) #debug'''

#__name__全局变量为模块提供一个方便的用户接口,或用于测试(以脚本的方式运行模块从而执行一些测试套件)。

# 6.1.2 模块搜索路径

# 当一个名为 spam 的模块被导入的时候,解释器首先寻找具有该名称的内置模块。

#如果没有找到,然后解释器从 sys.path 变量给出的目录列表里寻找名为 spam.py 的文件,这个目录列表取决于安装的默认设置;

print(sys.path)

'''['D:\\4_Project\\python-docs','D:\\4_Project','E:\\7_Anaconda\\Anaconda3-5.3.0-Windows-x86_64\\envs\\dockerenvs\\python36.zip','E:\\7_Anaconda\\Anaconda3-5.3.0-Windows-x86_64\\envs\\dockerenvs\\DLLs','E:\\7_Anaconda\\Anaconda3-5.3.0-Windows-x86_64\\envs\\dockerenvs\\lib','E:\\7_Anaconda\\Anaconda3-5.3.0-Windows-x86_64\\envs\\dockerenvs','E:\\7_Anaconda\\Anaconda3-5.3.0-Windows-x86_64\\envs\\dockerenvs\\lib\\site-packages','E:\\7_Anaconda\\Anaconda3-5.3.0-Windows-x86_64\\envs\\dockerenvs\\lib\\site-packages\\setuptools-28.8.0-py3.6.egg','E:\\7_Anaconda\\Anaconda3-5.3.0-Windows-x86_64\\envs\\dockerenvs\\lib\\site-packages\\pip-9.0.1-py3.6.egg','E:\\7_Anaconda\\Anaconda3-5.3.0-Windows-x86_64\\envs\\dockerenvs\\lib\\site-packages\\win32','E:\\7_Anaconda\\Anaconda3-5.3.0-Windows-x86_64\\envs\\dockerenvs\\lib\\site-packages\\win32\\lib','E:\\7_Anaconda\\Anaconda3-5.3.0-Windows-x86_64\\envs\\dockerenvs\\lib\\site-packages\\Pythonwin','E:\\6_Pycharm\\installer\\helpers\\pycharm_matplotlib_backend']'''

########

# 在初始化后,Python 程序可以更改 sys.path。包含正在运行脚本的文件目录被放在搜索路径的开头处,

# 在标准库路径之前。这意味着将加载此目录里的脚本,而不是标准库中的同名模块。除非有意更换,否则这是错误。如下:

'''import syssys.path.append('E:\\')print(sys.path)# ['E:\\7_Anaconda']import debug1# E盘'''

#注意,以上在E盘下面放了debug1.py,脚本里面的内容是print("E盘")

# sys.path 变量是一个字符串列表,用于确定解释器的模块搜索路径。该变量被初始化为从环境变量

# PYTHONPATH 获取的默认路径,或者如果 PYTHONPATH 未设置,则从内置默认路径初始化。你可以使用标

# 准列表操作对其进行修改:

# import sys

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

# 6.1.3 “编译过的”Python 文件

# 为了加速模块载入,Python 在 __pycache__ 目录里缓存了每个模块的编译后版本,名称为 module.version.pyc ,其中名称中的版本字段对编译文件的格式进行编码;

#它一般使用 Python 版本号。例如,在CPython 版本 3.3 中,spam.py 的编译版本将被缓存为 __pycache__/spam.cpython-33.pyc。此命名约定允许来自不同发行版和不同版本的 Python 的已编译模块共存。

#Python 根据编译版本检查源的修改日期,以查看它是否已过期并需要重新编译。这是一个完全自动化的过程。此外,编译的模块与平台无关,因此可以在具有不同体系结构的系统之间共享相同的库。

# Python 在两种情况下不会检查缓存。首先,对于从命令行直接载入的模块,它从来都是重新编译并且不存储编译结果;

# 其次,如果没有源模块,它不会检查缓存。

# 为了支持无源文件(仅编译)发行版本,编译模块必须是在源目录下,并且绝对不能有源模块。

###

# 补充

# Python是一门解释性语言,其实并不是那么简单,python程序会预编译生成*.pyc文件。

# 计算机是不能够识别高级语言的,所以当我们运行一个高级语言程序的时候,就需要一个“翻译机”来从事把高级语言转变成计算机能读懂的机器语言的过程。

# 这个过程分成两类,第一种是编译,第二种是解释。

# 编译型语言在程序执行之前,先会通过编译器对程序执行一个编译的过程,把程序转变成机器语言。运行时就不需要翻译,而直接执行就可以了。最典型的例子就是C语言。

# 解释型语言就没有这个编译的过程,而是在程序运行的时候,通过解释器对程序逐行作出解释,然后直接运行,最典型的例子是Ruby。

# Python是一门先编译后解释的语言。

# 当python程序运行时,编译的结果则是保存在位于内存中的PyCodeObject中,当Python程序运行结束时,Python解释器则将PyCodeObject写回到pyc文件中。

# 当python程序第二次运行时,首先程序会在硬盘中寻找pyc文件,如果找到,则直接载入,否则就重复上面的过程。

# pyc文件其实是PyCodeObject的一种持久化保存方式。

# pyc文件是py文件编译后生成的字节码文件(byte code)

# pyc文件经过python解释器最终会生成机器码运行。

# pyc文件是可以跨平台部署的

# 1.终端执行命令,生成单个pyc文件:

# python -m foo.py

#2.另外一种方式是通过代码来生成pyc文件。

# import py_compile

# py_compile.compile('/path/to/foo.py')

# 3.批量生成pyc文件

# 针对一个目录下所有的py文件进行编译。python提供了一个模块叫compileall:

# import compileall

# compileall.compile_dir(r'/path')

# 6.2 标准模块

# Python 附带了一个标准模块库

# 在终端命令行交互的模式下:

# 变量sys.ps1 和 sys.ps2 定义用作主要和辅助提示的字符串:

# 6.3 dir() 函数

# 内置函数 dir() 用于查找模块定义的名称。它返回一个排序过的字符串列表:

# 它列出所有类型的名称:变量,模块,函数,等等。

# import fibo

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

# 如果没有参数,dir() 会列出你当前定义的名称:

# print(dir()) #['__builtins__', '__name__', 'a', 'fib', 'fibo', 'sys']

#注意Python 附带了一个标准模块库,sys也是内置模块;(模块里可以有很多内置函数和内置变量)

# dir() 不会列出内置函数和变量的名称。如果你想要这些,它们的定义是在标准模块 builtins 中:

print("#"*30)

import builtins

print( dir(builtins) )

# ['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', ......'type', 'vars','zip']

#6.4 包

# 包是一种通过用“带点号的模块名”来构造 Python 模块命名空间的方法。例如,模块名 A.B 表示 A 包中名为 B 的子模块。

#正如模块的使用使得不同模块的作者不必担心彼此的全局变量名称一样,使用加点的模块名可以使得 NumPy 或 Pillow 等多模块软件包的作者不必担心彼此的模块名称一样。

# 假设你想为声音文件和声音数据的统一处理,设计一个模块集合(一个“包”),结构如下:

'''sound Top-level package__init__.py Initialize the sound packageformats Subpackage for file format conversions__init__.pywavread.pywavwrite.pyaiffread.pyaiffwrite.pyauread.pyauwrite.py...effects Subpackage for sound effects__init__.pyecho.pysurround.pyreverse.py...filters Subpackage for filters__init__.pyequalizer.pyvocoder.pykaraoke.py...'''

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

# 必须要有 __init__.py 文件才能让 Python 将包含该文件的目录当作包。

# __init__.py可以只是一个空文件,但它也可以执行包的初始化代码或设置 __all__ 变量;

# 包的用户可以从包中导入单个模块:

# import sound.effects.echo

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

# from sound.effects import echo

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

# from sound.effects.echo import echofilter

# 注意,当使用 from package import item 时,item 可以是包的子模块(或子包),也可以是包中定义的其他名称,如函数,类或变量。

# import 语句首先测试是否在package中定义了 item;如果没有,它假定它是一个模块并尝试加载它。如果找不到它,则引发 ImportError 异常。

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

# 6.4.1 从包中导入 *

# 找到包中存在哪些子模块,并将它们全部导入。这可能需要很长时间,导入子模块可能会产生不必要的副作用,这种副作用只有在显式导入子模块时才会发生。

# 唯一的解决方案是让包作者提供一个包的显式索引。

# 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,然后导入包中定义的任何名称。

# import sound.effects.echo

# import sound.effects.surround

# from sound.effects import *

# 在这个例子中,echo 和 surround 模块是在执行 from...import 语句时导入到当前命名空间中的,因为它们定义在 sound.effects 包中。(这在定义了 __all__ 时也有效。)

# 虽然某些模块被设计为在使用 import * 时只导出遵循某些模式的名称,但在生产代码中它仍然被认为是不好的做法。

# from package import specific_submodule是推荐的表示法。

# 6.4.2 子包参考

# 当包被构造成子包时,你可以使用绝对导入来引用兄弟包的子模块。例如:

# 如果模块 sound.filters.vocoder 需要在 sound.effects 包中使用 echo 模块,它可以使用 from sound.effects import echo 。

# 你还可以使用 import 语句的 from module import name 形式编写相对导入。这些导入使用前导点( leading dots)来指示相对导入中涉及的当前包和父包。例如,从 surround 模块,你可以使用:

# from . import echo

# from .. import formats

# from ..filters import equalizer

######

# 注意,相对导入是基于当前模块的名称进行导入的。由于主模块的名称总是 "__main__" ,因此用作Python 应用程序主模块的模块必须始终使用绝对导入。

######

# 6.4.3 多个目录中的包

# 包支持另一个特殊属性,__path__ 。(__init__.py除了__all__属性之外的一个特殊属性:__path__)

# 在__init__.py文件运行之前,该变量被初始化为一个包含 __init__.py 所在目录的列表。(通常这个列表就一个值:" __init__.py的路径")

# 这个变量可以被修改。

# 如果修改了这个变量会影响到后续的对这个包中的模块和子包的搜索。

# 虽然通常不需要此功能,但它可用于扩展程序包中的模块集。

######

#上面翻译可能不好理解,请参考下面英文:

'''Packages support one more special attribute, __path__.This is initialized to be a list containing the name of the directory holding the package’s __init__.py before the code in that file is executed.This variable can be modified; doing so affects future searches for modules and subpackages contained in the package.While this feature is not often needed, it can be used to extend the set of modules found in a package.'''

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值