版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
本章将集中介绍Python模块和如何把数据从模块中导入到编程环境中。同时也会涉及包的相关概念。模块是用来组织Python代码的方法,而包则是用来组织模块的。本章最后还会讨论一些模块支持从逻辑上组织Python代码。当代码量变得相当大的时候,我们最好把代码分成一Python允许"调入"一个模块,允许使用其他模块的属性来利用之前的工作成果,实现代码重用.这个把其他模块中属性附加到你的模块中的操作叫做导入(import)码片断就是模块(module)。如果说模块是按照逻辑来组织Python代码的方法,那么文件便是物理层上组织模块的方法。的名字加上扩展名.py。这里我们需要讨论一些关于模块文件结构的问题。与其它可以导入类(class)的语言不同,在Python中你导入的是模块或模块属性。本章的后面会详细的讨论名称空间,但从基本概念来说,一个名称空间就是一个从名称到对象的关系映射集合。我们已经明确地知道,模块名称是它们的属性名称中的一个重要部分。例如string模块中的atoi()函数就是string.atoi()。给定一个模块名之后,只可能有一个模块被导入到Python解释器中,所以在不同模块间不会出现名称交叉现象;所以每个模块都定义了它自己的唯一的名称空间。如果我在的模块mymodule里创建了一个atoi()函数,那么它的名字应该是mymodule.atoi()。所以即使属性之间有名称,但它们的完整名称(fullyqualifiedname)——通过句点属性标识指定了各自的名称空间-防止了名称的发生。mymodule.pymymodulePython搜索和搜索路径是两个不同的概念,前者是指查找某个文件的操作,后者是去查找一组。有时 发生这样的错误时,解释器会告诉你它无法请求的模块,可能的原因是模块不在搜索路径里,从而导致了路径搜索。一个是启动Python的s或命令行的PYTHONPATH环境变量。该变量的内容是一组用冒Python解释器启动之后,也可以这个搜索路径,它会被保存在sys模块的sys.path变量里。不过它已经不是冒号分割的字符串,而是包含每个独立路径的列表。下面是一个Unix机器搜索路径的样例。切记,搜索路径在不同系统下一般是不同的。['','/usr/local/lib/python2.x/','/usr/local/lib/python2.xt-sunos5','/usr/local/lib/python2.x/lib-tk','/usr/local/lib/python2.x/lib-dynload','/这只是个列表,所以我们可以随时随地对它进行修改。如果你知道你需要导入的模块是什么,而它的路径不在搜索路径里,那么只需要调用列表的append()方法即可,就像这样:修改完成后,你就可以加载自己的模块了。只要这个列表中的某个包含这个文件,它就会被正确导入。当然,这个方法是把追加在搜索路径的尾部。如果你有特殊需要,那么应该使用列表的insert()方法操作。上面的例子里,我们是在交互模式下修改sys.path的,在ImportError:Nomodulenamedmymodule使用sys.modules可以找到当前导入了哪些模块和它们来自什么地方。和sys.path不同,sys.modules是一个字典,使用模块名作为键(key),对应物理地址作为值(value。名称空间是名称(标识符)到对象的映射。向名称空间添加名称的操作过程涉及到绑定标识符到有如下的定义:改变一个名字的绑定叫做重新绑定,删除一个名字叫做解除绑定。11局部名称空间,全局名称空间和内建名称空间,但局部名称空间在执行期间是不断变化的,所以我们说"两个或三个"。从名称空间中这些名字依赖于它们的加载顺序,或是系统加载这些名称空Pythonbuiltins模块中的名字构成。随后加载执 模块,该模块包含内建函数,异常以及其他属性。在标准Python执行环境下, 的所有名字。Python曾经有一个限制执行模式,允许你修改builtins,只保留来自 的一部分,创建一个沙盒(sandbox)环境。但是,因为通过globals()和locals()内建函数判断出某一名字属于哪个名称空间。在本章后面详细好了,我们已经知道了什么是名称空间,那么它与变量作用域有什么关系呢?它们看起来极其相似。事实上也确实如此。名称空间是纯粹意义上的名字和对象间的映射关系,而作用域还了从用户代码的哪些物理位置可以到这些名字。图12-1展示了名称空间和变量作用域的关系。还要记得在程序执行过程中,局部名称空间和作用域会随函数调用而不断变化,而全局名称空图12- 名称空间和变量作用那么确定作用域的规则是如何联系到名称空间的呢?它所要做的就是名称查询.一个属了,你会得到这样的错误:覆盖的影响。图12-1的灰盒子展示了遮蔽效应。例如,局部名称空间中找到的名字会隐藏全局或内建名称空间的对应对象。这就相当于"覆盖"了那个全局变量。请参阅前面章节引入的这几bar=200bar=100
main,baris",执行代码,得到这样的输出 main,baris100callingfoo()...foo()函数局部名称空间里的bar变量覆盖了全局的bar变量。虽然bar存在于全局名称内容请参阅第11.8节。Python的一个有用的特性在于你可以在任何需要放置数据的地方获得一个名称空间。我们已经一章见到了这一特性,你可以在任何时候给函数添加属性(使用熟悉的句点属性标识)。foo.doc foo.version=0.2在本章,我们展示了模块是如何创建名称空间的,你也可以使用相同的方法它们虽然我们还没介绍面向对象编程(OOP,第13章),但我们一个简单的"oWorld!"例子:bag.x=100你可以把任何想要的东西放入一个名称空间里。像这样使用一个类(实例)是很好的,你甚至不需要知道一些关于OOP的知识(注解:类似这样的变量叫做实例属性。)不管名字如何,这个实随着学习的深入,你会发现OOP是多么地有用,比如在运行时临时(而且重要)变量的时候!正就让我们多用用它们吧!"(在交互模式解释器下导入this模块就可以看到完整的《Zen》)。import:importmodule1[,module2[,...Python做法没有什么不同。所以一般情况下,我们使用第一种格式。风格:importPython第模importPython(Python’sStyleGuide),PEP8。解释器执行到这条语句,如果在搜索路径中找到了指定的模块,就会加载它。该过程遵循作用域原则,如果在一个模块的顶层导入,那么它的作用域就是全局的;如果在函数中导入,那么它的from-import你可以在你的模块里导入指定的模块属性。也就是把指定名称导入到当前作用域。使用from-import多行导入特性是Python2.4为较长的from-import提供的。从一个模块导入许多属性时,import行会越来越长,直到自动换行,而且需要一个\。下面是PEP328提供的样例代码:from-importfromTkinterimportTk,Frame,Button,Entry,Canvas,TextfromTkinterimportLEFT,DISABLED,NORMAL,RIDGE,END真正的Python程序员应该使用Python的标准分组机制(圆括号)来创建更合理的多行导入语句:你可以在PEP328找到关于多行导入的内容import可能是它太长不便输入什么的,总之你不喜欢它。这已经成为Python程序员的一个普遍需求:使上边的例子中,我们没有使用longmodulename.attribute,而是使用short.attribute来from-imoortimport名称。类似这样...Python2.0as"Python2.6一个关键字。关于扩展导入语句的内容请参阅《Python语言参考》和PEP221。加载模块会导致这个模块被"执行"。也就是被导入模块的顶层代码将直接被执行。这通常包 。如果有检查 的操作,那么它也会被执行。本很简单[$foo.py],但执行一个标准库或是第包中的模块需要一定的技巧。)你可以在第14.4.3一节了解一个模块只被加载一次,无论它被导入多少次。这可以多重导入时代码被多次执行。例如你的模块导入了sys模块,而你要导入的其他5个模块也导入了它,那么每次都加载sys(或是其他模块)不是明智之举!所以,加载只在第一次导入时发生。调用from-import可以把名字导入当前的名称空间里去,这意味着你不需要使用属性/句点属性标识来模块的标识符。例如,你需要模块module中的var名字是这样被导入的:我们使用单个的var就可以它自身。把var导入到名称空间后就再没必要模块了。当然,你也可以把指定模块的所有名称导入到当前名称空间里:风格:限制使用"frommoduleimport在实践中,我们认为"frommoduleimport*"不是良好的编程风格,因为它"污染"当前名称空间,而且很可能覆盖当前名称空间中现有的名字;但如果某个模块有很多要经常的变量或者模块的名字很长,这也不失为一个方便的好办法。我们只在两种场合下建议使用这样的方法,一个场合是:目标模块中的属性非常多,反复键入模块名很不方便,例如Tkinter(Python/Tk)和NumPy(NumericPython)模块,可能还有socket模块。另一个场合是在交互解释器下,因为这样可以减少输入次数。块的原始名称空间。也就是说,绑定只是局部的而不是整个名称空间。这里我们提供了两个模块的代码:一个导入者,impter.py,一个被导入者,imptee.py。impter.py使用from-importfoo=fooimporter.pyfoofromimpteeabcfoofromimpter123foofromimptee:abcimportimportimptee 回首Python2.0当前功能。所以为了让Python程序员为新事物做好准备,Python实现了future指令。使用from-import定下来的时候修改程序。它的语法是:fromfutureimport只importfuture不会有任何变化,所以这是被的。(事实上这是允许的,但它不会如你所想的那样启用所有特性。)你必须显示地导入指定特性。你可以在PEP236找到关于 指令类似,有必要去警告用户不要使用一个即将改变或不支持的操作,这样他们会在新功能正式发布前采取必要措施。这个特性是很值得讨论的,我们这里分步讲解一下。首先是应用程序(员)接口(Applicationprogrammers'interface,APIPython程序(通过调用warnings模块)或是C中(通过PyErr_Warn()这个框架的另个部分是一些警告异常类的集合。Warning直接从Exception继承,作为所有UserWarningDeprecationWarningSyntaxWarningRuntimeWarning在第10章中有详细介绍。另一个组件是警告过滤器,由于过滤有多种级别和严重性,所以警告的数量和类型应该是可控sys.stderr警告的Python时,可以记录它的输出记录到日志文件中,而不是直接显示给终端用户。Python还提供了一个可以操作警告过滤器的API。最后,命令行也可以控制警告过滤器。你可以在启动Python解释器的时候使用-W选项。请参阅PEP230的文档获得你的Python版本的对应开关选项。Python2.1第一次引入警告框架。ZIP在2.3版中,Python加入了从ZIP归档文件导入模块的功能。如果你的搜索路径中存在一个包含Python模块(.py,.pyc,or.pyo文件)的.zip文件,导入时会把ZIP文件当作处理,在文件中搜索模块。如果要导入的一个ZIP文件只包含.py文件,那么Python不会为其添加对应的.pyc文件,这意味着如果一个ZIP归档没有匹配的.pyc文件时,导入速度会相对慢一点。同时你也可以为.zip文件加入特定的(子),例如/tmp/yolk.zip/lib只会从yolk归档的lib/子下导入。虽然PEP273PEP302提供的导入ZIPimporthookPEP302)们使用了"新"这个字,因为在这之前实现自定义导入器只能是使用一些很古老的模块,它们并不会
import通过sys模块""(或者叫"安装")它。查找器实例负责查找你的模块,如果它找到,那么它将返回一个载入器对象。查找器可以接受一个路径用以查找子包(subpackages)。载入器会把模块载入到内存。它负责完成创建一个Python模块所需要的一切操作,然后返回模块。sys.path_hookssys.path_importer_cache样就只需要path_hooks一次。最后,sys.meta_path用来保存一列需要在查询sys.path之前的实例,这些是为那些已经知道位置而不需要查找的模块准备的。meta-path已经有了指系统还为模块提供了一些功能上的支持.现在详细讨论他们importPython1.5加入 ()函数,它作为实际上导入模块的函数,这意味着import句调用importimportmodule_name变量是要导入模块的名称,globals是包含当前全局符号表的名字的字典,locals是包含局部符号表的名字的字典,fromlist是一个使用from-import语句所导入符号的globals,localsfromlistglobals()locals()importsyssys=importglobalsglobals()locals()部,局部名称空间代表在函数执行时候定义的所有名字,locals()函数返回的就是包含这些名字的字典。globals()会返回函数可的全局名字。globals()locals()全局空间。下边这段代码演示这两个函数的了使用:aString='bar'print"main'sglobals:",globals().keys()我们只在这里了字典的键,因为它的值在这里没有影响(而且他们会让行变得更长更难执行这个,我们得到如下的输出$main'sglobals:['doc','foo','name','builtinsmain'slocals:['doc','foo','name','builtinsfoo()'sglobals:['doc','foo','name','builtins']foo()'slocals:['anInt','aString']reload()module是你想要重新导入的模块。使用reload()的时候有一些标准。首先模块必须是全部导入(不是使用from-import),而且它必须被成功导入。另外reload()函数的参数必须是模块自身而不是包含模块名的字符串。也就是说必须类似reload(sys)而不是reload('sys')。模块中的代码在导入时被执行,但只执行一次.以后执行import语句不会再次执行这些代码,只是绑定模块名称。而reload()函数不同。包 结构,它定义了一个由模块和子包组成的Python应用程序执行环境。Python1.5加入了包,用来帮助解决如下问题: 结构而不是一大堆的文与类和模块相同,包也使用句点属性标识来他们的元素。使用标准的importfrom-import init.pyinit.py
init.py/init.pyinit.pyPhoneVoicedtaimportPhone from-import第法是只导入顶层的子包,然后使用属性/点操作符向下子包树fromPhoneimport1212')此外,我们可以还的子包fromPhoneogimportdial在我们上边的 结构中,我们可以发现很多的 .py文件。这些是初始化模块,from-import语句导入子包时需要用到它。如果没有用到,他们可以是空文件。程序员经常忘记为它们的包目录加入ImportWarning
.py文件,所以从Python2.5开始,这将会导致一个Wdfrom-importfrom-importall然而,这样的语句会导入哪些文件取决于操作系统的文件系统.所以我们在init.py中加入all变量.该变量包含执行这样的语句时应该导入的模块的名字.字)。包模块会把名字相同的标准库模块隐藏掉,因为它首先在包内执行相对导入,隐藏掉标为此,所有的导入现在都被认为是,也就是说这些名字必须通过Python路径(sys.path或是PYTHONPATH)来这个决定的基本原理是子包也可以通过sys.path,例如importPhone..og。在这个变化之前,从子包内模块中导入og是合理的。作为一个折中方案,Python允许通过在模块或包名称前置句点实现相对导入。信息请参阅第12.7.4节。从Python2.7开始,绝对导入特性将成为默认功能。(从Python2.5开始,你可以从 导入absolute_import,体验这个功能。)你可以参阅PEP328了解相关内容如前所述,绝对导入特性限制了模块作者的一些。失去了import语句的自由,必须有新import法,让程序员告诉导入者在子包的哪里查找某个模块。因为import语句总是绝对导入的,所以相对导入只应用于from-import语句。语法的第一部分是一个句点,指示一个相对的导入操作。之后的其他附加句点代表当前我们再来看看上边的例子。在og..Digital,也就是Digital.py模块中,我们不Python个警告,或者干脆不能工作:fromogimportdial from..FaximportG3.dial.2.5PythonPython2.6果没有使用相对导入,那么会显示一个警告信息。你可以在PEP328的文档中获得相关信息。当Python解释器在标准模式下启动时,一些模块会被解释器自动导入,用于系统相关操作。 模块,它会正常地被载入,这和 sys.modules作为键,它们的位置作为值。Windowssys.modules模块名,通过调用字典的keys()方法:'strop','nt','sys','builtin',Unix入的模块很类似'main','posix','sys','builtin',"frommoduleimport*"_importfoo._bar),这个隐藏数据的方法就不起作用了。Python2.1PythonMacOSXCygwin视,而需要被清除。在Unix(区分大小写)和Win32(不区分大小写)下,一切都很明了,但那些新的不区分大小写的系统不会被加入区分大小写的特性。PEP235其他系统上"hack"式的解决方法。就是为了让不区分大小写的导入正常工作,必须指定一个叫做PYTHONCASEOK的环境变量。Python会导入第一个匹配模块名(使用不区分大小写的习惯)。否则Python会执行它的原生区分大小写的模块名称匹配,导入第一个匹配的模块。从Python2.3开始,Python的模块文件开始支持除7位ASCII之外的其他编码。当然ASCII是默认的,你只要在你的Python模块头部加入一个额外的编码指示说明就可以让导入者使UnicodeASCII候不需要担心了(不需要的字符串放入"Unicode"里)。UTF-8#!/usr/bin/envpython如果你执行或导入了包含非ASCII的Unicode字符串而没有在文件头部说明,那么你会在Python2.3得到一个DeprecationWarning,而在2.5中这样做会导致语法错误。你可以在PEP263中得到关于源文件编码的相关内容。我们来看一个例子。假定我们的产品有一个很复杂令行接口(command-lineinterface OMH)omh4cli.pydefcli_util():defomh4cli():::假定大多控制器都要用到这里的(其实是空的)工具函数。命令行接口的OMH都被封装在omh4cli()函数里。如果我们要添加一个新令,那么它会被调用现在这个模块不断地增长,一些聪明的工程师会决定把新命令放入到的模块里,在原始模么你就不必在一个几兆的Python文件里搜索。在我们的例子中,有一个兴奋的经理要我们加入一个"非常好的特性"。创建一个新cli4vof.py,而不是把新内容集成到omh4cli.py里defcli4vof():前边已经提到,工具函数是每个命令必须的,而且由于不能把代码从主控制器出来,所以我们导入了主模块,在我们的控制器中添加对omh,omh4cli()的调用。问题在于主控制器omh4cli会导入我们的cli4vof模块(获得新命令的函数),而cli4vof也omh4cliPythonFile"/usr/prod/cli4vof.py",line3,in?注意返回消息中显示的对cli4vof的循环导入。问题在于要想调用工具函数,cli4vof必omh4cliomh4clicli4vof但在这里,omh4cli尝试导入cli4vof,而cli4vof也试着导入omh4cli。最后谁也不会完成导入工作,错误。这只是一个导入循环的例子。事实上实际应用中会出现更复杂的情况。importimport为什么了.。在我们的例子中,我们不能把importomh4cli移到最后,因为调用cli4vof()的时候omh4cli()名字还没有被载入。importomh4cliimportcli4vof()importomh4cli这样,从omh4cli()导入cli4vof()模块
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024版船舶股权转让争议解决条款3篇
- 2025年外研衔接版高一数学下册月考试卷含答案
- 2025年甘肃省建筑安全员知识题库
- 2025云南省建筑安全员A证考试题库及答案
- 制造业数字化转型的关键领域
- 2025年苏科新版八年级科学上册月考试卷
- 2024电商物流服务定制合同6篇
- 制造业数字化转型过程中的沟通与协作策略
- 2025版班组工前会工后会记录执行标准及培训实施合同3篇
- 2024美缝施工项目资金管理合同3篇
- 上海市徐汇区上海小学二年级上册语文期末考试试卷及答案
- 精密制造行业研究分析
- 心源性晕厥护理查房课件
- 2022-2023学年浙江省杭州市萧山区五年级(上)期末科学试卷(苏教版)
- 船舶辅机:喷射泵
- 岩土工程勘察服务投标方案(技术方案)
- 疼痛护理课件
- 副院长兼总工程师的岗位说明书
- 农民专业合作社章程参考
- 财务会计制度及核算软件备案报告书
- 肌骨超声简介
评论
0/150
提交评论