Python手册

如果你从Python解释器中退出然后重新进入,之前定义的名字(函数和变量)都丢失了。因此,如果你想写长一点的程序,使用文本编辑器来准备解释器的输入会更好,使用文件作为替代的输入。这也被称作创建脚本。当程序越来越长时,出于易于维护的原因,你可能会将程序分割为几个文件。你也可能想要在多个程序中使用很好用的一个函数,而不用将其定义拷贝到每一个程序中。

为了支持这些需求,Python提供了将定义放入一个文件的方式,并且在脚本或者解释器交互式实例中使用它们。这样的文件称为模块;模块中的定义可以导入到其他模块或者主模块中(在顶层执行的脚本和计算模式中可访问到的变量集合)。

模块就是一个包含Python定义和语句的文件。文件名是模块名并且带有

.py

后缀。在模块中,模块的名字(作为字符串),作为全局变量

__name__

的值,是可用的。例如,使用你最喜欢的文本编辑器在当前目录创建

fibo.py

文件,内容如下:

# Fibonacci numbers moduledef fib(n): # write Fibonacci series up to n

进入Python解释器,使用下列命令导入这个模块:

>>> import fibo

这个操作并不会讲

fibo

中定义的函数的名字导入到当前符号表中;只是导入模块的名字

fibo

。使用模块名字可访问到函数:

>>> fibo.fib(1000)1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987>>> fibo.fib2(100)

如果想要频繁使用函数,可以将其赋值给局部名字:

>>> fib = fibo.fib>>> fib(500)1 1 2 3 5 8 13 21 34 55 89 144 233 377

6.1 More on Modules

模块可以同时包含可执行语句和函数定义。可执行语句用来初始化模块。当模块名字出现在导入语句中时,这些可执行语句只执行一次[1]。(如果文件作为脚本,这些可执行也会执行)

每一个模块都有自己私有的符号表,这个符号表被所有定义在模块中的函数作为全局符号表使用。因此,模块的作者可以使用这些全局变量,而不用担心和用于全局变量偶然的名字冲突。另一方面,如果你知道自己在做什么,你可以使用与引用函数相同的方法来引用模块的全局变量,

modname.itemname

模块可以引用其他模块。将所有

import

语句放置到模块的开始处(或者脚本)是一个很好的习惯,但并不是强制的。被导入的模块名字将会被放置到当前模块的全局符号表中。

有一种导入语句的变种方法,将模块的名字直接导入到当前模块的符号表中。例如:

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

以上并不会引入模块的名字(在上面的例子中

fibo

不会被定义)。

甚至有一种方法可以导入模块中定义的所有名字:

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

这种方法导入所有不以下划线

_

开头的名字。大多数情况下,Python程序员不会使用这种方法,因为这会导入未知的名字集合到解释器中,也许还会屏蔽已经定义的一些名字。

需要注意,通常在实践中从模块或者包中导入所以名字是不鼓励使用的,因为会降低程序的易读性。然而,在交互式环境中使用它来减少打字输入是可行的。

注意: 出于性能原因,一个解释器会话中每个模块只导入一次。因此,如果模块被改变了,必须重启解释器;如果只想要交互式测试一个模块,使用

importlib.reload()

,例如:

import importlib; importlin.reload(modulename)

6.1.1 Executing modules as scripts

当使用以下命令运行Python模块:

python fibo.py <arguments>

模块中的代码会被执行,就像导入该模块一样,但是这时

__name__

被设置为

__main__

。这意味着以下代码会加入到模块末尾:

if __name__ == "__main__": import sys

模块即作为脚本执行,也可以作为模块导入,因为只有当模块作为

mian

文件执行时候,解析命令行的代码才会执行:

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

如果模块被导入,代码不会执行:

>>> import fibo>>>

这可以用来为使用者提供一个模块用户接口的使用约定,也可以用作测试(模块作为脚本时执行测试用例)

6.1.2 The Module Search Path

当模块

spam

被导入时,解释器首先搜索

built-in

模块。如果没有找到,解释器在变量

sys.path

提供的路径列表中搜索名为

spam.py

的文件。

sys.path

从下列位置初始化:

  • 包含输入脚本的目录(或者没有指定文件时的当前目录)
  • PYTHONPATH

    (目录名字集合,与shell环境变量

    PATH

    相似,也是环境变量)

  • 安装默认目录

注意: 在支持符号链接的文件系统,包含输入脚本的目录是符号链接指向的目录。也就是说包含符号链接的目录不会被加入到搜索路径中。

初始化后,Python程序可以修改

sys.path

。包含执行脚本的目录被放置到搜索路径的开始,在标准库路径之前。这意味着该目录中的脚本会被加载,而标准库目录中的同名模块不会被加载。这会引发错误,除非是有意替换标准库的模块。阅读Standard Modules获取更多信息。 (译注:自定义的模块不应与标准模块重名,否则标准模块会被覆盖。)

6.1.3 “Compiled” Python files

为加速模块加载,Python会在

__pycache__

目录中缓存每个模块的编译版本,缓存文件名为

module.version.pyc

version

编码了被编译文件的版本;通常包含了Python的版本号。例如,在

CPython release 3.3

中,文件

spam.py

的编译版本会被缓存为

__pycache__/spam.cpython-33.pyc

。这种命名约定允许来自不同Python发行版本的模块得以共存。

Python检查源文件的修改日期与编译版本,来确定编译版本是否过期,是否需要重新编译。这是一个完全自动化的过程。另外,编译模块是平台独立的,因此异构系统可以共享相同的库。

Python不会检查在两个环境中的缓存。首先,Python总是重新编译,并且不会存储直接从命令行加载的模块的结果。其次,如果没有源模块,Python不检查缓存。若要支持无源文件(只有编译版本)分布,那么编译的模块必须放在源文件目录中,并且源模块必需不存在。

给专家的建议:

  • 可以在命令行使用

    -O

    或者

    -OO

    开关来减少编译模块的大小。

    -O

    参数移除

    assert

    语句,

    -OO

    参数同时移除

    assert

    语句和

    __doc__

    字符串。由于一些程序依赖这些变量,那么只有当你确认你要这么做时,才能使用这两个参数。“优化的”模块有一个

    opt-

    标签并且通常更小。未来的发型版本可能改变优化的影响。

  • .pyc

    文件中读取的程序不会比从

    .py

    文件读取的程序跑得快;

    .pyc

    文件快的地方在于加载。

  • compileall

    模块可以为目录中的所有模块创建

    .pyc

    文件。

  • PEP 3147中有关系这点的更多信息,包括一个决策流程

6.2 Standard Modules

Python提供了标准模块库,在独立文档中描述,名为

Python Library Reference

(以后叫做

Library Reference

)。有一些模块内嵌入解释器中,这些模块不是语言核心的一部分,但是它们是内嵌的,这既是为性能考虑,也提供了访问如系统调用般的操作系统原生接口的方式。这些模块集合依赖底层平台的配置选项。例如

winreg

模块只在Windows系统中提供。一个特殊的模块值得注意:

sys

,这个模块内嵌在所有Python解释器中。变量

sys.ps1

sys.ps2

定义了主提示符和辅助提示符的字符串:

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

只有当解释器以交互模式运行才会定义这两个变量。

变量

sys.path

是决定解释器模块搜索路径的字符列表。该变量从环境变量

PYTHONPATH

,或者内置默认路径(

PYTHONPATH

未指定时)初始化。可以使用标准

list

操作修改它的值:

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

6.3 The dir() Function

内嵌函数

dir()

用于搜索模块定义的名字。返回一个有序字符串列表:

>>> import fibo, sys>>> dir(fibo)

不带参数使用

dir()

函数,会列出当前作用域的全部名字:

>>> a = [1, 2, 3, 4, 5]>>> import fibo>>> fib = fibo.fib>>> dir()

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

dir()

不会列出内嵌函数和变量的名字。如果希望列出,这些名字定义在标准模块

builtins

中:

>>> import builtins>>> dir(builtins)

6.4 Packages

包是使用“圆点模块名”结构化Python模块名字空间的方式。例如,模块名

A.B

表示包

A

中的子模块

B

。就像模块使得不同模块的作者免于担忧每个模块的全局名字一样,圆点模块名的使用使得多模块包(如

NumPy

或者Python图像库)的作者免于担忧每个模块的名字。

假设需要为统一音频文件和音频数据的处理设计一个模块的集合(包)。有许多不同的音频文件格式(通常通过扩展名辨认,如

.wav, .aiff, .au

),因此需要为不同文件格式的转换创建和维护一个持续增长的模块集合。也存在许多对音频数据不同的操作(例如混合,增加回声,增加均衡器函数,创建人造立体效果),因此需要额外编写执行这些操作的大量模块。以下是包的可能结构(以层级文件结构来表示):

sound/ Top-level package

导入包时,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

语句首先测试要导入的项是否在包中存在;如果不存在,Python假设这个项是模块并尝试加载它。如果最后寻找失败,

ImportError

异常抛出。

相对的,使用

import item.subitem.subsubitem

时,除了最后一项,每一项都必须是包;最后一项可以是模块或者包但是不能是前面的项中定义的类,函数或者变量。

6.4.1 Importing * From a Package

使用

from sound.effects import *

会发生什么?理想情况下,总是期望在文件系统中找出所有子模块,并全部导入。全部导入会耗费很长时间,并且导入子模块可能会有不期待的副作用,这些副作用应该在显式导入时发生。

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

import

语句遵循以下约定:如果包的

__init__.py

代码中定义了名为

__all__

的变量,那么使用

from package import *

时会导入该变量指定的所有模块。当包的新版本发布时,由包作者负责更新列表

__all__

。如果包作者不希望可以使用

from package import *

导入包中的模块,也可以不支持

__all__

。 例如,文件

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.echoimport sound.effects.surroundfrom sound.effects import *

这个例子中,

echo

surround

模块被导入到当前名字空间中,因为执行

from... import

时,它们已经定义在

sound.effects

包中定义了。(定义了

__all__

时同样有效)

尽管使用

import *

时只有符合特定模式的名字会被导出,但仍然不建议在生产代码中使用。

记住,使用

form Package import specific_submodle

没有错误。实际上,这是推荐的方法,除非当前模块需要使用其他包中的同名模块。

6.4.2 Intra-package References

当包中包含了子包结构(就如例子中的

sound

包),可以使用绝对导入的方式引用兄弟包中的子模块。例如,如果模块

sound.filters.vocoder

需要使用包

sound.effects

中的

echo

模块,可以使用

from sound.effects import echo

也可以使用

from modul import name

语句来相对导入模块。这种方式使用点

.

指示当前包和相对导入中涉及的父包。以

surround

模块为例:

from . import echofrom .. import formatsfrom ..filters import equalizer

相对导入基于当前模块的名字。由于主模块的名字总是

__main__

,要当做Python应用主模块使用的模块必须总是使用绝对导入的方式。

6.4.3 Packages in Multiple Directories

包还支持一个特殊属性,

__path__

。在

__init__.py

中的代码执行之前,属性

__path__

被初始化为一个列表,这个列表包含了持有该

__init__.py

文件的目录的路径。该变量可修改,这样做会影响将来的对包内模块和子包的搜索。

然而这个特性不总是需要的,它可以用来扩展包的模块集合

Footnotes

[1] 实际上,函数定义也是可“执行”的“语句”;模块级别的函数执行将函数的名字放置到模块的全局符号表中

喜欢的朋友加扣扣群+813622576 ,群内有免费资料供大家一起交流学习哦!!!

原文地址:https://www.cnblogs.com/zxcv1234/p/9451883.html

时间: 2024-11-05 23:35:10

Python手册的相关文章

解读python手册的例子a, b = b, a+b

Python手册上有个例子,用于输出10以内的斐波那契序列.代码如下: 1 a, b = 0, 1 2 while b < 10: 3 print(b) 4 a, b = b, a+b 用到了一些Python的特性. 研究后解释下 第一行, a, b = 0, 1 赋值多个变量.等价 a = 0 , b = 1 第四行,a, b = b, a+b , 相当于 a=b , b = a+b 分析下执行过程 第一次循环 a = 0, b = 1 输出 b为1, 并计算后a = 1,b = 1 第二次循

Python 手册(一)

Python 手册 Guido van Rossum Fred L. Drake,  Jr., editor PythonLabs Email: [email protected] Release  2.3 July 29, 2003 About this document ... Python Tutorial, July 29, 2003, Release 2.3 This document was generated using the  LaTeX2HTML translator. La

Python 手册——参数传递以及交互模式

我们先来看参数传递. 调用解释器时,脚本名和附加参数之传入一个名为sys.argv的字符串列表.没有脚本和参数时,它至少也有一个 元素:sys.argv[0]此时为空字符串.脚本名指定为‘ - ’(表示标准输入)时,sys.argv[0]被设置为‘ - ’,使用-c 指令时,sys.argv[0]被设定为‘  -c ’.  -c 命令之后的参数不会被  Python 解释器的选项处理机制所截获,而是留在sys.argv 中,供脚本命令操作. 接下来我们再来看交互模式. 从tty读取命令时,我们称

Python 手册——开胃菜

如果你写过大规模的Shell脚本,应该会有过这样的体会:你还非常想再加一些别的功能进去,但它已经太大. 太慢.太复杂了:或者这个功能需要调用一个系统函数,或者它只适合通过C来调用……通常这些问题还不足 以严肃到需要用C重写这个Shell:可能这个功能需要一些类似变长字符串或其它一些在Shell脚本中很容易找到 的数据类型(比如文件名的有序列表),但它们用C来实现就要做大量的工作,或者,你对C还不是很熟悉. 另一种情况:可能你需要使用几个C库来工作,通常C的编写/编译/测试/重编译周期太慢.你需要

Python 手册——解释器及其环境

错误处理: 有错误发生时,解释器打印一个错误信息和栈跟踪(监视)器?.交互模式下,它返回主提示符,如果从文件 输入执行,它在打印栈跟踪器后以非零状态退出.(异常可以由try语句中的except子句来控制,这样就不会出 现上文中的错误信息) 有一些非常致命的错误会导致非零状态下退出,这由通常由内部矛盾和内存溢出造成. 所有的错误信息都写入标准错误流:命令中执行的普通输出写入标准输出. 在主提示符或附属提示符输入中断符(通常是Control-C or DEL)就会取消当前输入,回到主命令行.2.1执

Python 手册——调用解释器

通常Python的解释器被安装在目标机器的 /usr/local/bin/python 目录下:把 /usr/local/bin 目录放进你的UNIX Shell 的搜索路径里,确保它可以通过输入python来启动.因为安装路径是可选的,所以也有可能安装在其它位置,你可以与安装Python的用户或系统管理员联系.(例如,/usr/local/python就是一个很常见的选择)输入一个文件结束符(UNIX上是Ctrl+D,Windwos上是Ctrl+Z)解释器会以0值退出(就是说,没有什么错误,正

Python 手册——Python的非正式介绍

在后面的例子中,区分输入和输出的方法是看是否有提示符(“>>> ”和“.. ”):想要重复这些例子的话,你就要在提示符显示后输入所有的一切:没有以提示符开始的行,是解释器输出的信息.需要注意的是示例中的 从属提示符用于多行命令的结束,它表示你需要输入一个空行. 本手册中的很多示例都包括注释,甚至有一些在交互提示符中折行.Python中的注释以符号“#”起始,一直到 当前行的结尾.注释可能出现在一行的开始,也可能跟在空格或程序代码之后,但不会出现在字符串中,字符 串中的#号只代表#号. 示

[读书笔记]流畅的Python(Fluent Python)

<流畅的Python>这本书是图灵科技翻译出版的一本书,作者Luciano Ramalho. 作者从Python的特性角度出发,以Python的数据模型和特殊方法为主线,主要介绍了python的集合类型(sequence.mapping.set等).把函数作为一等对象来使用.类的构建.新的文件控制流程(生成器.上下文管理器.协程).用描述符来从底层解释Python对象属性的存储等各个方面. 书中主要围绕Python标准库展开,不涉及过多的异常实用的标准库以外的包. 0x01:这本书适合谁看?

Python模块学习笔记— —random

Python中的random模块用于生成随机数. random.random 函数原型 random.random() 生成一个范围在[0,1)的随机浮点数. import random print random.random() random.uniform 函数原型 random.uniform(a,b) 生成一个指定范围内的随机浮点数,两个参数一个是上限,一个是下限.如果a > b,则生成的随机数范围在[b,a].否则, 范围在[a,b]. import random print rand