Chinaunix首页 | 论坛 | 博客
  • 博客访问: 5783215
  • 博文数量: 291
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 7924
  • 用 户 组: 普通用户
  • 注册时间: 2016-07-06 14:28
个人简介

阿里巴巴是个快乐的青年

文章分类

全部博文(291)

文章存档

2018年(21)

2017年(4)

2016年(5)

2015年(17)

2014年(68)

2013年(174)

2012年(2)

分类: Python/Ruby

2013-03-26 23:34:21

一、模块与包
        Python模块,简单说就是一个.py文件,其中可以包含我们需要的任意Python代码。不是所有程序都有相关联的.py文件——比如:sys模块就内置于Python中,还有些模块是使用其它语言(最常见的是C语言)实现的。对于程序而言,模块使用哪种语言实现并不重要,因为所有模块的导入与使用的方式都是相同的。
        在进行导入时,有几种语法格式可以使用,比如:
        import importable
        import importable1, importable2, ..., importableN
        import importable as preferred_name
        这里,importable通常是一个模块,比如collections,但也可以是一个包或包中的模块,如果是这种情况,就将每一部分使用句点(.)进行分隔,比如os.path。
        通常将所有import语句部署在.py文件的起始处,并放置在shebang行以及模块文档之后。建议先导入标准库模块,之后是第三方库模块,最后才是自定义模块。
        下面给出了一些其它的导入语法格式:
        from importable import object as preferred_name
        from importable import object1, object2, ..., objectN
        from importable import(object1, object2, object3, object4,
                object5, ..., objectN)
        from importable import *
        下面给出一些import语句实例:
        import os
        printf(os.path.basename(filename))
        
        import os.path as path
        print(path.basename(filename))

        from os import path
        print(path.basename(filename))

        from os.path import basename
        print(basename(filename))

        from os.path import *
        print(basename(filename))
        
        Python如何知道去哪里寻找要导入的模块与包?内置sys模块中包含一个名为sys.path的列表,其中存放了构成Python路径的目录列表,其中第一个目录就是程序所在目录,即便程序可能是从其它目录中调用的。如果设置了环境变量PYTHONPATH,那么其中指定的路径就是sys.path列表中的下一个路径,最后的那些路径是访问Python标准库时所需要的——安装Python时会进行设置。初次导入一个模块时,如果该模块不是内置模块,那么Python会依次在sys.path列出的每个路径中搜索该模块。一种快速检测某个模块是否存在的方法是尝试导入该模块,为此,可以在控制台中带命令行选项-c调用解释器,其后跟随一个导入语句,比如:
        python -c "import Music"
        如果该命令产生异常,则说明不存在该模块,否则意味着已经被使用。
        在导入某个模块时,Python首先检查该模块是否已经导入,如果尚未导入,Python就会执行该模块的字节码编译的代码,从而创建该模块提供的变量、函数以及其它对象,并在内部记录该模块已经被导入了。在后续每次对该模块导入时,将不进行任何操作。
        使用字节码编译的文件具有更快的启动速度,因为解释器只需要加载并运行代码,而不需要加载、编译、运行代码。安装Python时,标准库通常是作为安装进程的一部分进行了字节码编译的。
1、包
        简单地说,包就是一个目录,其中包含一组模块和一个__init__.py文件。比如:假定我们有一组模块文件,用于读写不同类型的图形文件格式,比如Bmp.py,Jpeg.py,Png.py,Tiff.py与Xpm.py,所有这些文件都提供了load()、save()等函数。我们可以将模块保存在程序所在目录,但对于使用大量自定义模块的大型程序,图形程序模块将被分散。通过将其放置在自己的子目录,比如Graphics,就可以将这些模块保存在一起,如果同时向Graphics目录中添加一个空的__init__.py文件,该目录就变为一个包:
        Graphics/
            __init__.py
            Bmp.py
            Jpeg.py
            Png.py
            Tiff.py
            Xpm.py
        只要Graphics目录是我们程序目录的子目录(或存在于Python路径中),我们就可以导入这些模块中的任意模块并使用之。我们必须确保顶级模块名(Graphics)不与标准库中的任何顶级名相同,以避免名称冲突。(在Linux上,可以通过将模块名的首字母大写就很容易地实现,因为所有标准库中的模块名称都是小写字母表示的)。下面展示如何导入并使用自己的模块:
        import Graphics.Bmp
        image = Graphics.Bmp.load("bashful.bmp")
        有些情况下,使用单独的一条语句导入某个包的所有模块会带来很多方便,为此,我们必须编辑该包的__init__.py文件,使其包含一条语句,并使用该语句指定要加载哪些模块,为此,这一语句必须将模块列表复制给特殊变量__all__。比如,下面给出的就是Graphics/__init__.py文件中添加的必要语句:
        __all__ = ["Bmp", "Jpeg", "Png", "Tiff", "Xpm"]
        这就是为了完成上述要求所必须添加的唯一一条语句,完成这一工作后,就可以使用一种不同的导入语句了:
        from Graphics import *
        image = Xpm.load("sleepy.xpm")
        from package import * syntax这一语法格式直接导入了在__all__列表中指定的所有模块,因此,这一导入操作后,不仅Xpm模块可以直接访问,其中指定的所有其它模块都可以直接访问。这一语法格式也可以应用于模块,即from module import *,这样模块中定义的所有函数、变量以及其它一些对象(那些名称以下划线引导的对象除外)都将被导入。如果需要精确控制导入的对象,可以在模块本身中定义一个__all__列表,在这种情况下,将只导入在__all__列表中指定的对象。
        Python支持对包进行任意层次的嵌套,因此,我们可以在Graphics目录下色绘制子目录,比如Vector,并在其中放置相关文件,比如Eps.py与Svg.py:
        Graphics/
            __init__.py
            Bmp.py
            Jpeg.py
            Png.py
            Tiff.py
            Vector/
                __init__.py
                Eps.py
                Svg.py
            Xpm.py
        要使得Vector目录也是一个包,也必须在其中放置一个__init__.py文件,该文件可以为空,也可以包含一个__all__列表。可以如下来访问一个嵌套的包:
        import Graphics.Vector.Eps
        image = Graphics.Vector.Eps.load("sneezy.eps")
2、自定义模块
        由于模块实质上就是.py文件,因此,创建模块时并不需要形式化。如果希望自定义模块能对所有程序都是可用的,就有几个中方法可以采用:
        (1)将该模块放置在Python分发的site-packages子目录中,该目录存在于Python路径中,因此,其中任何模块都可以被发现。
        (2)为该模块创建一个专门目录,并将环境变量PYTHONPATH设置为包含此目录。
        (3)将此模块放置在本地的site-packages子目录中,该目录也存在于Python路径中。
        后两种方法的优势在于可以讲模块代码独立于正式的安装之外。

二、Python标准库概览
1、字符串处理
        String模块提供了一些有用的常量,比如string.ascii_letters、string.hexdigits。还提供了string.Formatter类以提供自定义的字符串格式化器。
        Struct模块提供了一些函数,可用于将数字、布尔型变量以及字符串打包为字节对象(以其二进制表示形式),或从字节对象中拆分为适当的类型。在需要对数据进行处理,使其发送到以C语言编写的底层库(或从其中接收数据)时,这是有用的。
        Python中功能最强大的字符串处理模块是re(正则表达式)模块。
2、io.StringIO类
        Python提供了两种将文本写入到文件的不同方法,一种是使用文件对象的write()方法,另一种是使用print()函数,并将其关键字参数file设置为打开并等待写入的文件对象,比如:
        print("An error message", file=sys.stdout)
        sys.stdout.write("Another error message\n")
        上面两行文本都将被打印到sys.stdout,这是一个文件对象,表示“标准输出流”——这通常是控制台,不同于sys.stderr(“错误输出流”),区别仅在于后者是非缓冲的。默认情况下,print()函数会添加一个新行,我们可以通过将关键字参数end设置为空字符串来阻止这一点。
        有些情况下,将本来要写入到文件中去的输出信息捕获到字符串中是有用的,这可以使用io.StringIO类实现,该类提供的对象可以像文件对象一样使用,但其中以字符串来存放写入到其中的任何数据。如果对io.StringIO对象赋予一个初始化字符串,就可以像对文件一样进行读取。
        如果已执行import io,就可以存取io.StringIO,并用其捕获本来要输入的文件对象(比如sys.stdout)中的输出信息:
        sys.stdout = io.StringIO()
        如果将上面一行代码放置在程序的起始处,那么在导入之后与使用sys.stdout之前,发送给sys.stdout的任意文本实际上都将发送给io.StringIO,这是该行代码创建的一个类似于文件的对象,并且该对象替换了标准的sys.stdout文件对象。现在当前面展示的print()与sys.stdout.write()执行后,其输出将输出到io.StringIO对象,而非控制台(任意时刻,我们都可以使用语句sys.stdout = sys.__stdout__来恢复原始的sys.stdout)。
        通过调用io.StringIO.getvalue()函数,我们可以获取所有写入到io.StringIO对象的字符串,这里具体调用的是sys.stdout.getvalue()——其返回值是一个字符串,其中包含已经写入到所有行。该字符串可以打印出来,或者保存到日志中,或通过网络连接发送——就像任何其它字符串一样。
3、命令行程序设计
        如果我们需要处理那些在控制台中被重定向到文本,或那些包含在命令行中列出的文件中的文本,那么可以使用fileinput模块的fileinput.input(),该函数会对控制台中重定向的所有行(如果存在)进行迭代,或对命令行中列出的文件中的所有行进行迭代,就像对一个连续的行序列一样。通过使用fileinput.filename()与fileinput.lineno(),该模块可以在任意时刻报告当前文件名与行号。有两个单独的模块可以处理命令行选项,分别是optparse与getopt。
4、数学与数字
        除内置的int、float与complex之外,标准库还提供了decimal.Decimal与fractions.Fraction这两种数据类型。有3个可用的数值型标准库:math,用于标准的数学函数;cmath,用于复数数学函数;random,提供了很多用于随机数生成的函数。
        Python的数值型抽象基类是在numbers模块中定义的,该基类可用于检测某个对象的具体类型,比如:对象x,isinstance(x, numbers.Number)可以检测x是否是任何一种类型的数字。
5、时间与日期
        calendar与datetime模块提供了处理日期与时间的函数(基于理想化的罗马日历)。
        time模块可以处理时间戳,时间戳实际上是数字,其中存放的是自初始时间(在UNIX上位1970-01-01 T00:00:00)至今经过的秒数。该模块可用于获取UTC(协调世界时)格式表示的机器当前时间,或夏令时形式的本地时间,也可以创建日期、时间以及多种格式的日期/时间字符串,也可以用于分析包含日期与时间的字符串。
6、算法与组合数据类型
        bisect模块提供的函数可用于搜索有序序列,也可以用于向其中插入项,同时又保证序列的有序性。heapq模块提供的函数可以将序列转换为最小堆——一种组合数据类型,其中第一项(索引位置为0)总是最小的,也可以用于向其中插入或移除项,同时又保证序列仍然是一个最小堆。
        collections包提供了字典collections.defaultdict与组合数据类型collections.named-tuple,还提供了collections.UserList与collections.UserDict等数据类型。另一种类型是collections.deque,该类型与list类似,区别在于collections.deque在开始与结尾处添加或移除项有很快的速度。collections.OrderedDict具有正常dicts相同的API,尽管在对字典项目进行迭代式,这些项目总是以插入顺序返回,而且popitem()方法总是返回最近被添加的项目。collections.Counter类是dict的一个子类,提供了一种保持各种计数的便捷而且快速的方法。
        array模块提供了序列类型array.array,可以以非常节省空间的方式存储单词或字符,其中只能存放固定的对象类型。
        weakref模块提供了创建弱引用的功能即如果对某个对象仅有的引用时弱引用,那么该对象仍然可以被调度进入垃圾收集,这可以防止某些对象仅仅因为存在对其的引用而保存在内存中。我们可以检测对某个对象的弱引用是否存在,如果存在,就可以访问该对象。
7、文件格式、编码与数据持久性
        标准库提供了对大量标准文件格式与编码的广泛支持。base64模块提供的函数可以读写RFC3548中指定的base16、base32与base64等编码格式。quopri模块提供的函数可以读写“quoted-printable”格式,该格式在RFC1521中定义,并用于MIME(多用途Internet邮件扩展)数据。uu模块提供的函数可以读写uuencoded数据。RFC1832定义了外部数据表示标准,xdrlib模块提供的函数可以读写这种格式。
        还有些模块提供了对采用最流行的格式的存档文件的读写功能。bz2模块可以处理.bz2文件,gzip模块可以处理.gz文件,tarfile模块可以处理.tar、.tar.gz(即.tgz)与.tar.bz2文件,zipfile模块可以处理.zip文件。
        对某些音频格式数据的处理功能也在某些模块中实现,比如:aifc模块可以处理AIFF(音频交换文件格式),wave模块可以处理.wav文件。有些音频数据格式可由audioop模块进行操纵,sndhdr模块提供可两个函数,可用于确定文件存放的是哪种类型的音频数据以及某些特性,比如采样率。
        除了对多种文件格式的支持外,标准库中还有一些包与模块提供了对数据持久性的支持。pickle模块用于向磁盘中存储或从磁盘中取回任意的Python对象(包括整个组合)。标准库也支持各种类型的DBM文件——类似于字典,差别在于其项存储在磁盘中,而非内存中,并且其键与值都必须是bytes对象或字符串。
8、文件、目录与进程处理
        Shutil模块提供了用于文件与目录处理的高层函数,包括复制文件与整个目录的shutil.copy()函数与shutil.copytree()函数,用于移动目录树的shutil.move()函数,以及用于移动整个目录树(包括非空的)的shutil.rmtree()函数。
        临时文件与目录应该使用tempfile模块创建,该模块提供了必要的函数,比如tempfile.mkstemp(),并以尽可能安全的方式创建临时对象。
        filecmp模块可用于对文件进行比较(使用filecmp.cmp()函数),也可以用于对整个目录进行比较(使用filecmp.compfiles函数)。
        Python程序一种非常强大而有效的用法是调度其它程序的运行,这可以使用subprocess模块完成,该模块可以调度其它进程,使用管道在其间进行通信,并取回其结果。一种更有效的替代方案是使用multiprocessing模块,该模块提供了广泛的工具,可用于将工作载荷分布到多个进程,并可以累积结果,通常可用于替代多线程。
        os模块提供了对操作系统功能的访问接口,并且是平台无关的。提供了os.environ、os.getcwd、os.chdir、os.access、os.listdir、os.stat、os.mkdir、os.make-dirs、os.rmdir、os.removedirs、os.remove、os.rename、os.walk、os.path等。
9、网络与Internet程序设计
        用于网络与Internet程序设计的包与模块是Python标准库的主要组成部分。在最底层,socket模块提供了大多数基本的网络功能,包括用于创建socket的函数、用于进行DNS(域名系统)查询的函数以及处理IP(Internet协议)地址的函数等。加密与认证的socket则可以使用ssl模块建立。socketserver模块提供了TCP(传输控制协议)服务器与UDP(用户数据报协议)服务器,这些服务器可以直接处理请求,也可以创建单独的进程(通过forking)或单独的线程来分别处理每个请求。异步的客户端与服务器socket处理可以使用asyncore模块以及构建在其上的更高层的asynchat模块来实现。
        Python定义了WSGI(Web服务器网关接口),旨在为Web服务器以及Python编写的应用程序之间提供一个标准接口。wsgiref包提供了WSGI的参考实现,http.server模块提供了一个HTTP服务器,http.cookies模块与http.cookiejar模块提供了用于管理cookies的函数,cgi模块与cgitb模块提供对CGI脚本的支持,客户端的HTTP请求由http.client模块提供,HTML与XHTML文档可以使用urllib.parser模块解析,URL可以使用urllib.parser模块创建与分析,robots.txt文件夹可以使用urllib.robotparser模块进行分析,json模块可以读写JSON表示的数据,xmlrpc.client与xmlrpc.server模块提供了对XML-RPC(远程过程调用)的支持,ftplib模块提供FTP功能,nntplib模块提供NNTP功能,telnetlib模块提供TELNET功能,smtpd模块提供了一个SMTP(简单邮件传输协议)服务器,在email客户端模块中,smtplib用于SMTP,imaplib用于IMAP4(Internet消息访问协议),poplib用于POP3(邮局协议)。
        如果感觉标准库的包与模块尚不足以提供足够的网络功能,那么可以参考Twisted()提供的全面的第三方网络库,还有很多可用的web程序库,包括用于创建web应用程序的Django()等则提供了完全的web框架与内容管理系统。
10、XML
        在分析XML文档时,有两种广泛采用的方法。一种是DOM(文档对象模型),另一种是SAX(用于XML的简单API)。标准库提供了两个DOM分析器,一个是由xml.dom模块提供的,另一个是由xml.dom.minidom模块提供的。SAX分析器则只有xml.sax模块提供的一个。xml.parsers.expat模块可用于分析带expat的XML文档,前提是expat库是可用的。也存在一些第三方库,比如lxml。
11、其它模块
        标准库提供了一个单元测试框架,由unittest模块实现——这实际是Java JUnit测试框架的Python版。logging模块提供了用于日志相关操作的统一接口,pprint可用于打印Python对象,threading模块提供了对创建线程化应用程序的支持,queue模块提供三种不同类型的thread-safe队列,使用tkinter模块的TK库提供GUI功能,abc模块提供了用于创建抽象基类的必要函数,copy模块提供了copy.copy()函数与copy.deepcopy()函数。
        对外部函数的访问即对共享库(Windows中的.dll文件,Mac OS X的.dylib文件,Linux中的.so文件)中函数的访问,可以使用ctypes模块实现。Python还提供了C API,因此,使用C语言创建自定义数据类型与函数,并使其为Python所用是可能的。
        


阅读(6856) | 评论(2) | 转发(0) |
给主人留下些什么吧!~~

wgzh19892014-03-05 15:10:31

文明上网,理性发言...赞一个

scq2099yt2013-04-06 13:54:17

文明上网,理性发言...