Python Tutorial(七):输入和输出

有几种方式来呈现程序的输出,数据可以以人类可读的形式打印,或者写到文件里面将来使用。本章我们将讨论这些可能性。

7.1 输出格式

到目前为止,我们遇到了两种方式来写值,表达式语句和print()函数。(第三种方式是用文件对象的write()方法,标准的输出文件可以被引用为sys.stdout)

通常你希望对输出格式有更多的控制而不是简单的以空格分隔进行打印。有两种方式来格式化输出;第一种方式是所有的字符串处理都自己做;使用字符串的切片和链接操作可以创建出你想象的任何布局。字符串类型有一些方法可以执行有用的操作把字符串填充到指定的列宽。第二种方式是使用str.format()方法。

string模块包含一个模板类提供另一种方式把值替换到字符串里面。

当然,还有一个问题,怎样把值转化为字符串,幸运的,Python有方式可以把任何值转化为字符串,把这个值传递到repr()或者str()函数。

str()函数的目的是以人类可读的形式返回值的表示形式。repr()函数的目的是产生一个解释器可读的表示形式(或者将强制产生一个语法错误如果没有相等的语法)。对于那些对人类没有特别表示形式的对象,str()将返回repr()的值。许多值,像数字或列表和字典结构,对于任何一个函数返回同样的表示。字符串,特殊情况下,有两个不同的表示。一些示例:

下面是两种方式来写一个平方和立方的表:

注意在第一个示例里,每一列直接都加入了一个空格,通过print()的工作方式,它总是在它的参数之间加入空格。

这个示例演示了字符串对象的str.rjust()方法,它把字段右对齐并通过在左边填充空格达到指定的宽度。有些相似的方法str.ljust()和str.center()。这些方法不写任何东西,它们仅仅返回一个新的字符串。如果输入字符串太长,并不截断字符串,直接返回它,这样会搅乱你的列布局,但是通常比其他的方法更好。其它情况值可能被截断了。(如果你真想截断的话,可以加一个切片操作符,x.ljust(n)[:n])

有另外一个方法,str.zfill(),它在字符串的左边添加零,它能够理解正负号:

str.format()方法的基本使用像这样:

花括号和它里面的字符(叫做格式字段)被传入str.format()方法里面的对象替换,花括号里面的数字可以用来引用传入str.format()方法里面的对象的位置:

如果str.format()方法里面使用了关键字参数,可以使用这些参数的名字来引用它们的值:

位置参数和关键字参数可以被任意结合:

!a(应用ascii())!s(应用str())!r(应用repr())可以用来在格式化前转换值:

一个可选的:和格式化指示符可以跟在字段名字的后面,这允许在如何格式化值上面有更大的控制。下面的示例圆周率Pi保留三位小数:

在:后面传一个整数使那个字段具有最小整数的字符宽度。这可以使表格变得漂亮:

如果你有一个很长的格式化字符串并且你不想把它分开,较好的方法是使用名字而不是位置来引用被格式化的变量。这可以简单的通过传一个字典和使用方括号访问键值来实现:

这也可以使用**把字典当作关键字参数来实现:

这是特别有用的,当结合内建函数vars(),它返回一个包含所有本地变量的字典。

7.1.1 旧的字符串格式化

%操作符也可以用来进行字符串格式化。它解释左边的参数(必须像一个sprintf()样式的格式字符串)被应用于右边的参数,从这个格式化操作返回字符串结果。例如:

因为str.format()非常新,许多Python代码仍然使用%操作符,然而,旧的格式化样式最终将从语言中删除,str.format()应该被广泛使用。

7.2 读写文件

open()返回一个文件对象,通常使用两个参数,open(filename, mode):

第一个参数是一个字符串包含文件名字,第二个参数是另一个字符串包含几个字符描述文件将被使用的方式。方式可以是r当文件被只读时,w是只写(已经存在的同名文件将被擦除),a是打开文件进行追加,任何写入文件的数据自动的加到最后面。r+打开文件可以读写,方式参数是可选的,如果忽略的话就假定是r。

通常,文件以文本模式打开,这意味着,从文件里读出和写入字符串,被一个指定的编码进行编码(默认是UTF-8)。b追加到方式后面以二进制的模式打开文件,数据的读出和写入都以字节对象的形式。这种模式用于所有的不包含文本的文件。

在文本模式,默认的是,在读的时候把平台特定的行结束(Unix是\n,Windows是\r\n)符转换为\n,在写的时候把\n转换为平台特定的行结束符。这种幕后的文件数据修改对于文本文件是没问题的,但是将会破坏二进制数据像JPEG或EXE文件。当读写这样的文件时要慎用二进制模式。

7.2.1 文件对象的方法

这个部分接下类的示例,将假定有一个叫f的文件对象已经被创建。

读一个文件的内容,调用f.read(size),它读一定数量的数据,并以字符串或字节对象的形式返回。size是一个可选的数字参数。当size被忽略或是负数时,整个文件的内容会被读出并返回。如果文件的大小是你机器内存的两倍,那就是你的问题。否则,最多的字节被读出并返回。如果达到了文件的末尾,f.read()将返回一个空字符串:

f.readline()从文件中读出一行,换行字符\n被留在了字符串的末尾,只有在文件的最后一行时会被忽略,前提是文件不是以一个新行结束。这使得返回值非常清晰明白,如果f.readline()返回一个空字符串,表明文件的末尾已经达到,同时,一个空白行被表示为一个\n,只包含一个换行符的字符串:

f.readlines()返回一个列表,包含文件里面所有的数据行。如果给定一个可选的参数sizehint,从文件里读取很多的字节,足够多的来完成一行,并且返回这些行。这通常允许有效的以行的形式来读取一个大文件,而不用把整个文件加载到内存里。只有完成的行会被返回:

一个可选的方式来读取行是循环一个文件对象。这样可以是内存有效,快速,并且代码更简单:

这个可选的方式比较简单,但是不提供细粒度的控制。因为两种方式管理行的缓存不同,它们不能被混合在一起。

f.write(string)把字符串的内容写入文件,返回写入字符的数目:

要写入一些不是字符串的东西,需要先转化为字符串:

f.tell()返回一个整数给出文件对象在文件中的位置,从文件的开头以字节数目来衡量。要改变文件对象的位置,使用f.seek(offset, from_what)。这个位置是在一个参考点加上偏移量算出来的,参考点是用from_what参数来选择的。0表示从文件开头,1表示当前位置,2表示文件的末尾作为参考点。它可以被忽略,默认是0,表示使用文件的开头作为参考点:

在文本文件里(在打开模式字符串里面没有b),只有相对于文件开头的寻找被允许(例外情况是可以使用seek(0, 2)寻找文件的末尾)。

当你用完一个文件时,调用f.close()来关闭它,并释放因打开文件而占用的任何系统资源。在调用f.close()后,尝试再使用文件对象将自动的失败:

在处理文件对象时使用with关键字是一个很好的实践。它的好处是在文件使用完后会被合适的关闭,即使在使用过程中有异常发生。它比写相等的try-finally块要短的多:

文件对象有一些其它的方法,像isatty()和truncate()使用频率比较少,查阅参考库获得完整的文件对象指南。

7.2.2 pickle模块

字符串可以容易地写入到文件和从文件里读出。数字就要稍微花费一些努力,因为read()方法只返回字符串,将不得不被传递给像int()这样的函数,它接受一个字符串像123并且返回它的数字值123。然而,当你想要保存比较复杂的数据类型像列表,字典或类的实例时,事情会变得更加复杂。

为了不让用户经常的写和调试代码来保存复杂的数据类型,Python提供了一个标准的模块叫做pickle。这是一个令人难以置信的模块,可以采用几乎任何Python对象(甚至一些Python代码的形式),并把它转换为一个字符串表示;这个过程被叫做pickling。从字符串表示重新构造对象被叫做unpickling。在pickling和unpickling之间,对象的字符串表示或许已经被存入一个文件或数据,或通过网络发送到一些远程机器。

如果你有一个对象x,和一个文件对象f已经被打开用于写入,最简单的来pickle对象只要一行代码:

为了再次的unpickle对象,如果f是一个文件对象已经被打开用于读出:

pickle是一个标准的方式使Python对象被其它程序来进行存储或重新使用,或者被相同的程序在将来进行调用;对于它的技术术语是一个持久化对象。因为pickle是如此的被广泛使用,许多写Python扩展的作者都非常小心来确保新的数据类型像矩阵可以被合适的pickle和unpickle。

本文是对官方网站内容的翻译,原文地址:http://docs.python.org/3/tutorial/inputoutput.html

posted on 2013-01-07 15:21  编程新说(李新杰)  阅读(5107)  评论(0编辑  收藏  举报