There are several ways to present the output of a program; data can be printed in a human-readable form, or written to a file for future use. This chapter will discuss some of the possibilities.
有幾種方法可以表現(xiàn)程序的輸出結(jié)果;數(shù)據(jù)可以用可讀的結(jié)構(gòu)打印,也可以寫入文件供以后使用。本章將會討論幾種可行的做法。
So far we've encountered two ways of writing values: expression
statements and the print statement. (A third way is using
the write() method of file objects; the standard output file
can be referenced as sys.stdout
. See the Library Reference for
more information on this.)
我們有兩種大相徑庭的輸出值方法:表達(dá)式語句和 print 語句。(第三種訪求是使用文件對象的 write() 方法,標(biāo)準(zhǔn)文件輸出可以參考 sys.stdout
。詳細(xì)內(nèi)容參見庫參考手冊。)
Often you'll want more control over the formatting of your output than
simply printing space-separated values. There are two ways to format
your output; the first way is to do all the string handling yourself;
using string slicing and concatenation operations you can create any
lay-out you can imagine. The standard module
string contains some useful operations
for padding strings to a given column width; these will be discussed
shortly. The second way is to use the %
operator with a
string as the left argument. The %
operator interprets the
left argument much like a sprintf()-style format
string to be applied to the right argument, and returns the string
resulting from this formatting operation.
可能你經(jīng)常想要對輸出格式做一些比簡單的打印空格分隔符更為復(fù)雜的控制。有兩種方法可以格式化輸出。第一種是由你來控制整個字符串,使用字符切片和聯(lián)接操作就可以創(chuàng)建出任何你想要的輸出形式。標(biāo)準(zhǔn)模塊 string 包括了一些操作,將字符串填充入給定列時,這些操作很有用。隨后我們會討論這部分內(nèi)容。第二種方法是使用 %
操作符,以某個字符串做為其左參數(shù)。 %
操作符將左參數(shù)解釋為類似于 sprintf() 風(fēng)格的格式字符串,并作用于右參數(shù),從該操作中返回格式化的字符串。
One question remains, of course: how do you convert values to strings?
Luckily, Python has ways to convert any value to a string: pass it to
the repr() or str() functions. Reverse quotes
(``
) are equivalent to repr(), but their use is
discouraged.
當(dāng)然,還有一個問題,如何將(不同的)值轉(zhuǎn)化為字符串?很幸運(yùn),Python總是把任意值傳入 repr() 或 str() 函數(shù),轉(zhuǎn)為字符串。相對而言引號 (``
)等價于repr(),不過不提倡這樣用。
The str() function is meant to return representations of values which are fairly human-readable, while repr() is meant to generate representations which can be read by the interpreter (or will force a SyntaxError if there is not equivalent syntax). For objects which don't have a particular representation for human consumption, str() will return the same value as repr(). Many values, such as numbers or structures like lists and dictionaries, have the same representation using either function. Strings and floating point numbers, in particular, have two distinct representations.
函數(shù) str() 用于將值轉(zhuǎn)化為適于人閱讀的形式,而 repr() 轉(zhuǎn)化為供解釋器讀取的形式(如果沒有等價的語法,則會發(fā)生 SyntaxError 異常) 某對象沒有適于人閱讀的解釋形式的話, str() 會返回與 repr() 等同的值。很多類型,諸如數(shù)值或鏈表、字典這樣的結(jié)構(gòu),針對各函數(shù)都有著統(tǒng)一的解讀方式。字符串和浮點(diǎn)數(shù),有著獨(dú)特的解讀方式。
Some examples:
>>> s = 'Hello, world.' >>> str(s) 'Hello, world.' >>> repr(s) "'Hello, world.'" >>> str(0.1) '0.1' >>> repr(0.1) '0.10000000000000001' >>> x = 10 * 3.25 >>> y = 200 * 200 >>> s = 'The value of x is ' + repr(x) + ', and y is ' + repr(y) + '...' >>> print s The value of x is 32.5, and y is 40000... >>> # The repr() of a string adds string quotes and backslashes: ... hello = 'hello, world\n' >>> hellos = repr(hello) >>> print hellos 'hello, world\n' >>> # The argument to repr() may be any Python object: ... repr((x, y, ('spam', 'eggs'))) "(32.5, 40000, ('spam', 'eggs'))" >>> # reverse quotes are convenient in interactive sessions: ... `x, y, ('spam', 'eggs')` "(32.5, 40000, ('spam', 'eggs'))"
Here are two ways to write a table of squares and cubes:
以下兩種方法可以輸出平方和立方表:
>>> for x in range(1, 11): ... print repr(x).rjust(2), repr(x*x).rjust(3), ... # Note trailing comma on previous line ... print repr(x*x*x).rjust(4) ... 1 1 1 2 4 8 3 9 27 4 16 64 5 25 125 6 36 216 7 49 343 8 64 512 9 81 729 10 100 1000 >>> for x in range(1,11): ... print '%2d %3d %4d' % (x, x*x, x*x*x) ... 1 1 1 2 4 8 3 9 27 4 16 64 5 25 125 6 36 216 7 49 343 8 64 512 9 81 729 10 100 1000
(Note that one space between each column was added by the way print works: it always adds spaces between its arguments.)
(需要注意的是使用 print 方法時每兩列之間有一個空格:它總是在參數(shù)之間加一個空格。)
This example demonstrates the rjust() method of string objects, which right-justifies a string in a field of a given width by padding it with spaces on the left. There are similar methods ljust() and center(). These methods do not write anything, they just return a new string. If the input string is too long, they don't truncate it, but return it unchanged; this will mess up your column lay-out but that's usually better than the alternative, which would be lying about a value. (If you really want truncation you can always add a slice operation, as in "x.ljust( n)[:n]".)
以上是一個 rjust() 函數(shù)的演示,這個函數(shù)把字符串輸出到一列,并通過向左側(cè)填充空格來使其右對齊。類似的函數(shù)還有 ljust() 和 center()。這些函數(shù)只是輸出新的字符串,并不改變什么。如果輸出的字符串太長,它們也不會截?cái)嗨,而是原樣輸出,這會使你的輸出格式變得混亂,不過總強(qiáng)過另一種選擇(截?cái)嘧址驗(yàn)槟菢訒a(chǎn)生錯誤的輸出值。(如果你確實(shí)需要截?cái)嗨梢允褂们衅僮,例如? "x.ljust( n)[:n]"。)
There is another method, zfill(), which pads a numeric string on the left with zeros. It understands about plus and minus signs:
還有一個函數(shù), zfill() 它用于向數(shù)值的字符串表達(dá)左側(cè)填充0。該函數(shù)可以正確理解正負(fù)號:
>>> '12'.zfill(5) '00012' >>> '-3.14'.zfill(7) '-003.14' >>> '3.14159265359'.zfill(5) '3.14159265359'
Using the %
operator looks like this:
可以如下這樣使用 %
操作符:
>>> import math >>> print 'The value of PI is approximately %5.3f.' % math.pi The value of PI is approximately 3.142.
If there is more than one format in the string, you need to pass a tuple as right operand, as in this example:
如果有超過一個的字符串要格式化為一體,就需要將它們傳入一個元組做為右值,如下所示:
>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 7678} >>> for name, phone in table.items(): ... print '%-10s ==> %10d' % (name, phone) ... Jack ==> 4098 Dcab ==> 7678 Sjoerd ==> 4127
Most formats work exactly as in C and require that you pass the proper
type; however, if you don't you get an exception, not a core dump.
The %s
format is more relaxed: if the corresponding argument is
not a string object, it is converted to string using the
str() built-in function. Using *
to pass the width
or precision in as a separate (integer) argument is supported. The
C formats %n
and %p
are not supported.
大多數(shù)類 C 的格式化操作都需要你傳入適當(dāng)?shù)念愋停贿^如果你沒有定義異常,也不會有什么從內(nèi)核中主動的彈出來。(however, if you don't you get an exception, not a core dump)使用 %s
格式會更輕松些:如果對應(yīng)的參數(shù)不是字符串,它會通過內(nèi)置的 str() 函數(shù)轉(zhuǎn)化為字符串。Python支持用 * 作為一個隔離(整型的)參數(shù)來傳遞寬度或精度。Python 不支持 C的 %n
和 %p
操作符。
If you have a really long format string that you don't want to split
up, it would be nice if you could reference the variables to be
formatted by name instead of by position. This can be done by using
form %(name)format
, as shown here:
如果可以逐點(diǎn)引用要格式化的變量名,就可以產(chǎn)生符合真實(shí)長度的格式化字符串,不會產(chǎn)生間隔。這一效果可以通過使用form %(name)format
結(jié)構(gòu)來實(shí)現(xiàn):
>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678} >>> print 'Jack: %(Jack)d; Sjoerd: %(Sjoerd)d; Dcab: %(Dcab)d' % table Jack: 4098; Sjoerd: 4127; Dcab: 8637678
This is particularly useful in combination with the new built-in vars() function, which returns a dictionary containing all local variables.
這個技巧在與新的內(nèi)置函數(shù) vars() 組合使用時非常有用,該函數(shù)返回一個包含所有局部變量的字典。
open() returns a file object, and is most commonly used with two arguments: "open(filename, mode)".
open() 返回一個文件,通常的用法需要兩個參數(shù): "open(filename, mode)"。
>>> f=open('/tmp/workfile', 'w') >>> print f <open file '/tmp/workfile', mode 'w' at 80a0960>
The first argument is a string containing the filename. The second
argument is another string containing a few characters describing the
way in which the file will be used. mode can be 'r'
when
the file will only be read, 'w'
for only writing (an existing
file with the same name will be erased), and 'a'
opens the file
for appending; any data written to the file is automatically added to
the end. 'r+'
opens the file for both reading and writing.
The mode argument is optional; 'r'
will be assumed if
it's omitted.
第一個參數(shù)是一個標(biāo)識文件名的字符串。第二個參數(shù)是由有限的字母組成的字符串,描述了文件將會被如何使用?蛇x的模式 有: 'r'
,此選項(xiàng)使文件只讀; 'w'
,此選項(xiàng)使文件只寫(對于同名文件,該操作使原有文件被覆蓋); 'a'
,此選項(xiàng)以追加方式打開文件; 'r+'
,此選項(xiàng)以讀寫方式打開文件;如果沒有指定,默認(rèn)為 'r'
模式。
On Windows and the Macintosh, 'b'
appended to the
mode opens the file in binary mode, so there are also modes like
'rb'
, 'wb'
, and 'r+b'
. Windows makes a
distinction between text and binary files; the end-of-line characters
in text files are automatically altered slightly when data is read or
written. This behind-the-scenes modification to file data is fine for
ASCII text files, but it'll corrupt binary data like that in JPEGs or
.EXE files. Be very careful to use binary mode when reading and
writing such files. (Note that the precise semantics of text mode on
the Macintosh depends on the underlying C library being used.)
在Windows 和 Macintosh平臺上, 'b'
模式以二進(jìn)制方式打開文件,所以可能會有類似于 'rb'
,'wb'
, 'r+b'
等等模式組合。Windows平臺上文本文件與二進(jìn)制文件是有區(qū)別的,讀寫文本文件時,行尾會自動添加行結(jié)束符。這種后臺操作方式對ASCII 文本文件沒有什么問題,但是操作 JPEG 或 .EXE這樣的二進(jìn)制文件時就會產(chǎn)生破壞。在操作這些文件時一定要記得以二進(jìn)制模式打開。(需要注意的是Mactiontosh 平臺上的文本模式依賴于其使用的底層C庫)。
The rest of the examples in this section will assume that a file
object called f
has already been created.
本節(jié)中的示例都默認(rèn)文件對象 f
已經(jīng)創(chuàng)建。
To read a file's contents, call f.read(size)
, which reads
some quantity of data and returns it as a string. size is an
optional numeric argument. When size is omitted or negative,
the entire contents of the file will be read and returned; it's your
problem if the file is twice as large as your machine's memory.
Otherwise, at most size bytes are read and returned. If the end
of the file has been reached, f.read()
will return an empty
string (""
).
要讀取文件內(nèi)容,需要調(diào)用 f.read(size)
,該方法讀取若干數(shù)量的數(shù)據(jù)并以字符串形式返回其內(nèi)容,字符串長度為數(shù)值size 所指定的大小。如果沒有指定 size或者指定為負(fù)數(shù),就會讀取并返回整個文件。當(dāng)文件大小為當(dāng)前機(jī)器內(nèi)存兩倍時,就會產(chǎn)生問題。正常情況下,會盡可能按比較大的size 讀取和返回?cái)?shù)據(jù)。如果到了文件末尾,f.read()
會返回一個空字符串(""
)。
>>> f.read() 'This is the entire file.\n' >>> f.read() ''
f.readline()
reads a single line from the file; a newline
character (\n
) is left at the end of the string, and is only
omitted on the last line of the file if the file doesn't end in a
newline. This makes the return value unambiguous; if
f.readline()
returns an empty string, the end of the file has
been reached, while a blank line is represented by '\n'
, a
string containing only a single newline.
f.readline()
從文件中讀取單獨(dú)一行,字符串結(jié)尾會自動加上一個換行符,只有當(dāng)文件最后一行沒有以換行符結(jié)尾時,這一操作才會被忽略。這樣返回值就不會有什么混淆不清,如果如果 f.readline()
返回一個空字符串,那就表示到達(dá)了文件末尾,如果是一個空行,就會描述為'\n´
,一個只包含換行符的字符串。
>>> f.readline() 'This is the first line of the file.\n' >>> f.readline() 'Second line of the file\n' >>> f.readline() ''
f.readlines()
returns a list containing all the lines of data
in the file. If given an optional parameter sizehint, it reads
that many bytes from the file and enough more to complete a line, and
returns the lines from that. This is often used to allow efficient
reading of a large file by lines, but without having to load the
entire file in memory. Only complete lines will be returned.
f.readlines()
返回一個列表,其中包含了文件中所有的數(shù)據(jù)行。如果給定了sizehint參數(shù),就會讀入多于一行的比特?cái)?shù),從中返回多行文本。這個功能通常用于高效讀取大型行文件,避免了將整個文件讀入內(nèi)存。這種操作只返回完整的行。
>>> f.readlines() ['This is the first line of the file.\n', 'Second line of the file\n']
f.write(string)
writes the contents of string to
the file, returning None
.
f.write(string)
將 string 的內(nèi)容寫入文件,返回
None
。
>>> f.write('This is a test\n')
To write something other than a string, it needs to be converted to a string first:
如果需要寫入字符串以外的數(shù)據(jù),就要先把這些數(shù)據(jù)轉(zhuǎn)換為字符串。
>>> value = ('the answer', 42) >>> s = str(value) >>> f.write(s)
f.tell()
returns an integer giving the file object's current
position in the file, measured in bytes from the beginning of the
file. To change the file object's position, use
"f.seek(offset, from_what)". The position is
computed from adding offset to a reference point; the reference
point is selected by the from_what argument. A
from_what value of 0 measures from the beginning of the file, 1
uses the current file position, and 2 uses the end of the file as the
reference point. from_what can be omitted and defaults to 0,
using the beginning of the file as the reference point.
f.tell()
返回一個整數(shù),代表文件對象在文件中的指針位置,該數(shù)值計(jì)量了自文件開頭到指針處的比特?cái)?shù)。需要改變文件對象指針話話,使用"f.seek(offset,from_what)" 。指針在該操作中從指定的引用位置移動offset 比特,引用位置由 from_what 參數(shù)指定。 from_what值為0表示自文件起初處開始,1表示自當(dāng)前文件指針位置開始,2表示自文件末尾開始。 from_what 可以忽略,其默認(rèn)值為零,此時從文件頭開始。
>>> f = open('/tmp/workfile', 'r+') >>> f.write('0123456789abcdef') >>> f.seek(5) # Go to the 6th byte in the file >>> f.read(1) '5' >>> f.seek(-3, 2) # Go to the 3rd byte before the end >>> f.read(1) 'd'
When you're done with a file, call f.close()
to close it and
free up any system resources taken up by the open file. After calling
f.close()
, attempts to use the file object will automatically fail.
文件使用完后,調(diào)用 f.close()
可以關(guān)閉文件,釋放打開文件后占用的系統(tǒng)資源。調(diào)用 f.close()
之后,再調(diào)用文件對象會自動引發(fā)錯誤。
>>> f.close() >>> f.read() Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: I/O operation on closed file
File objects have some additional methods, such as isatty() and truncate() which are less frequently used; consult the Library Reference for a complete guide to file objects.
文件對象還有一些不太常用的附加方法,比如 isatty() 和truncate() 在庫參考手冊中有文件對象的完整指南。
Strings can easily be written to and read from a file. Numbers take a
bit more effort, since the read() method only returns
strings, which will have to be passed to a function like
int(), which takes a string like '123'
and
returns its numeric value 123. However, when you want to save more
complex data types like lists, dictionaries, or class instances,
things get a lot more complicated.
我們可以很容易的讀寫文件中的字符串。數(shù)值就要多費(fèi)點(diǎn)兒周折,因?yàn)?tt class="method">read() 方法只會返回字符串,應(yīng)該將其傳入 int()方法中,就可以將 '123'
這樣的字符轉(zhuǎn)為對應(yīng)的數(shù)值123。不過,當(dāng)你需要保存更為復(fù)雜的數(shù)據(jù)類型,例如鏈表、字典,類的實(shí)例,事情就會變得更復(fù)雜了。
Rather than have users be constantly writing and debugging code to save complicated data types, Python provides a standard module called pickle. This is an amazing module that can take almost any Python object (even some forms of Python code!), and convert it to a string representation; this process is called pickling. Reconstructing the object from the string representation is called unpickling. Between pickling and unpickling, the string representing the object may have been stored in a file or data, or sent over a network connection to some distant machine.
好在用戶不必要非得自己編寫和調(diào)試保存復(fù)雜數(shù)據(jù)類型的代碼。 Python提供了一個名為 pickle的標(biāo)準(zhǔn)模塊。這是一個令人贊嘆的模塊,幾乎可以把任何 Python對象 (甚至是一些 Python 代碼段。┍磉_(dá)為為字符串,這一過程稱之為封裝 ( pickling)。從字符串表達(dá)出重新構(gòu)造對象稱之為拆封( unpickling)。封裝狀態(tài)中的對象可以存儲在文件或?qū)ο笾,也可以通過網(wǎng)絡(luò)在遠(yuǎn)程的機(jī)器之間傳輸。
If you have an object x
, and a file object f
that's been
opened for writing, the simplest way to pickle the object takes only
one line of code:
如果你有一個對象 x
,一個以寫模式打開的文件對象 f
,封裝對像的最簡單的方法只需要一行代碼:
pickle.dump(x, f)
To unpickle the object again, if f
is a file object which has
been opened for reading:
如果 f
是一個以讀模式打開的文件對象,就可以重裝拆封這個對象:
x = pickle.load(f)
(There are other variants of this, used when pickling many objects or when you don't want to write the pickled data to a file; consult the complete documentation for pickle in the Python Library Reference.)
(如果不想把封裝的數(shù)據(jù)寫入文件,這里還有一些其它的變化可用。完整的pickle 文檔請見Python 庫參考手冊)。
pickle is the standard way to make Python objects which can be stored and reused by other programs or by a future invocation of the same program; the technical term for this is a persistent object. Because pickle is so widely used, many authors who write Python extensions take care to ensure that new data types such as matrices can be properly pickled and unpickled.
pickle 是存儲 Python 對象以供其它程序或其本身以后調(diào)用的標(biāo)準(zhǔn)方法。提供這一組技術(shù)的是一個持久化對象( persistent object )。因?yàn)?pickle 的用途很廣泛,很多 Python 擴(kuò)展的作者都非常注意類似矩陣這樣的新數(shù)據(jù)類型是否適合封裝和拆封。
譯者:劉鑫(march.liu AT gmail DOT com) 由:limodou轉(zhuǎn)(limodou AT gmail DOT com) CHM 文件制作:Colin.Wang 2007年9月