第12章 输入/输出
很多时候, 会想让程序和用户交互, 从用户那得到输入, 打印结果; 使用input()和print()函数; 对于输出可以使用str(字符串)类的方法; 例如, 使用rjust()来获取一个指定宽度的字符串;
另一个常见的输入/输出类型是处理文件, 创建, 读和写文件是很多程序必需的功能;
用户输入
1
2
3
4
5
6
7
8
9
10
11
|
def reverse(text):
return text[:: - 1 ]
def is_palindrome(text):
return text = = reverse(text)
something = input ( '输入文本: ' )
if (is_palindrome(something)):
print ( "是的,这是回文" )
else :
print ( "不,这不是回文" )
|
[回文palindrome: 顺读倒读都一样的词语: ADA 国王国]
>使用切片特性来颠倒文本; seq[a:b]获取从a到b来自序列的切片; 还可以提供一个第三个确定步长的参数, 切片的默认步长是1, 返回一个连续文本的一部分; 步长 -1 将返回逆向文本;
>imput()将一个字符串作为参数, 显示给用户; 然后等用户输入+回车, input()将返回用户输入的文本;
>获取文本并颠倒reserve()它, 如果原始文本和颠倒文本相等, 那么文本是回文;
查找所有标点符号: http://grammar.ccc.commnet.edu/grammar/marks/marks.htm
文件
可以通过创建一个file类对象来打开文件, 使用read, readline或write进行文件读写; 对文件能否读写取决于打开文件时指定的模式; 当你完成对文件的操作的时候, 调用close方法告诉python文件的使用已经完成了;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
poem = '''\
Programming is fun
When the work is done
if you wanna make your work also fun:
use Python!
'''
f = open ( 'poem.txt' , 'w' ) # open for 'w'riting
f.write(poem) # 文本写入文件
f.close() # 关闭文件
f = open ( 'poem.txt' ) # 如果不指定打开模式,默认为'读'
while True :
line = f.readline()
if len (line) = = 0 : # 0长度表示文件结尾
break
print (line, end = '') #py2使用print line, 另起一行
f.close() # 关闭文件
|
>通过内置函数open, 指定文件名和需要打开的模式; [py2需要指明打开的文件名和模式创建一个file类的实例 file('poem.txt', 'w')]; 模式可以为 'r' 读, 'w' 写, 'a' 追加; 还可以指定是否已文本格式 't' 或二进制模式 'b' 读, 写或追加; 更多模式查看 help(open), open默认是读方式打开文本格式的文件;
>w模式打开文件, 使用write方法写文件, 最后close;
>然后再次打开文件, 以默认/读模式open; 循环中使用readline读文件的每一行; 这个方法返回包括行末换行符的一个完整行; 所以当一个空的字符串[换行符不为空]被返回的时候, 表示文件末以及到达了, 停止循环;
Note 因为从文件读到的内容已经以换行符结尾, 而print()函数在屏幕上默认会换行打印文本, 所以指定end=''禁止产生新行;
存储器
python提供标准模块pickle, 可以在文件中存储任何python对象, 随后可以把它完整地取出来, 这被称为持久地存储对象;
[py2有一个cPickle模块, 功能和pickle完全相同, 但是使用C编写的, 速度快很多;]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
import pickle as pk
# 我们将要存储对象的文件名
shoplistfile = 'shoplist.data'
# 购物清单
shoplist = [ '苹果' , '芒果' , '胡萝卜' ]
# Write to the file
f = open (shoplistfile, 'wb' )
pk.dump(shoplist, f) # dump the object to a file
f.close()
del shoplist # remove the shoplist
# Read back from the storage
f = open (shoplistfile, 'rb' )
storedlist = pk.load(f) # 从文件载入对象
print (storedlist)
|
Note import...as语法, 编译使用更短的模块名称 [别名]; 有助于切换模块; [别名不变, 只需要更新模块名]
Note 要在文件中存储对象, 必须以wb模式 write+binary 二进制格式的方式open文件, 然后使用dump函数, 把对象放入文件中; 这个过程称为 储存;
>使用load函数返回取回的对象, 这个过程称为 取储存;
第13章 异常
当程序中出现异常状况, 就会发出异常; 例如, 读取的文件不存在, 不小心删除正在运行的程序... 这些情况下使用异常处理;
如果程序有一些无效的语句, python会引发异常, 并告诉你有错误要处理;
错误
e.g. print的首字母错误地写成了大写P
1
2
3
4
5
|
>>> Print ( '世界你好' )
Traceback (most recent call last):
File "<pyshell#0>" , line 1 , in <module>
Print ( '世界你好' )
NameError: name 'Print' is not defined
|
>NameError, 错误信息的打印是错误处理程序完成的;
异常
尝试读取用户的输入, 在中间按ctrl-d:
1
|
s = input ( '输入一些东西 --> ' )
|
py会产生EOFError错误, 意味着发现了一个不希望看到的文件结束符号;
处理异常
使用try..except语句处理异常, 基本上把通常的语句放在try块, 把错误处理程序放在except块;
1
2
3
4
5
6
7
8
|
try :
text = input ( '输入一些东西 --> ' )
except EOFError: # Ctrl-d
print ( '为什么你要输入文件结束符呢?' )
except KeyboardInterrupt: # Ctrl-c
print ( '你取消了操作。' )
else :
print ( '你输入了 {0}' . format (text))
|
把可能导致异常/错误的语句放在try块, 把处理程序放在except子句/块中; except子句可以处理一个指定的错误/异常, 或一个圆括号括起来的错误/异常列表; 如果没有提供错误或异常的名字, 它将处理所有的错误和异常;
Note 每一个try子句, 必须有至少一个except子句与之相对应;
如果错误或异常没有被捕获处理, 默认的python处理器就会被调用; 它会终止程序的运行, 打印一个消息;
可以让try...except关联else从句, 当没有异常发生, else从句将被执行;
引发异常
使用raise语句引发异常; 需要指明错误/异常的名称和伴随异常触发的异常对象; 可以引发的错误或异常应该分别是一个Error或Exception类的直接或间接派生类;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
class ShortInputException(Exception):
'''一个用户定义的异常类。'''
def __init__( self , length, atleast):
Exception.__init__( self )
self .length = length
self .atleast = atleast
try :
text = input ( '输入一些东西 --> ' )
if len (text) < 3 :
raise ShortInputException( len (text), 3 )
# 像通常一样可以继续其它的工作
except EOFError:
print ( '\n为什么输入文件结束符?' )
except ShortInputException as ex:
print ( '输入短的例外: 输入有 {0} 长, 预期至少 {1}' \
. format (ex.length, ex.atleast))
else :
print ( 'No exception was raised.' )
|
>创建了自定义的异常类型, ShortInputException, 也可以使用预定义的异常/错误; 新的异常有两个域: length和atleast;
>except从句中, as 后面跟的变量表示错误/异常; 类似形参和实参的概念, except从句中使用异常对象的length和atleast字段. 打印相应的消息;
[py2中expect的格式是 except ShortInputException, x: ]
try..finally
假如在读文件的时候, 希望在无论异常是否发生的情况下都关闭文件, 就需要使用finally块来完成;
Note 在try块下, 可以同时使用except从句和finally块; 如果要同时使用它们, 要把其中一个嵌入另外一个;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
import time
try :
f = open ( 'poem.txt' )
while True : # 通常的读文件
line = f.readline()
if len (line) = = 0 :
break
print (line, end = '')
time.sleep( 1.5 ) # 确保它运行了一会儿
except KeyboardInterrupt:
print ( '!! 你取消了从文件读取操作。' ) #ctrl-c
finally :
f.close()
print ( '(清理:关闭文件)' )
|
>time.sleep会延迟2秒; 在程序运行时按ctrl-c可以中断/取消程序的运行;
>KeyboardInterrupt异常发生程序退出, 在程序退出前finally子句被执行, 文件对象总会被关闭;
with语句
在try块中获取资源和随后在finally块释放资源是一种常见模式; 因此还有一个with语句, 用干净的代码运行这个模式;
1
2
3
|
with open ( "poem.txt" ) as f:
for line in f:
print (line, end = '')
|
>和前面的例子一样输出; 不同的是, 使用带有with语句的open函数, 把关闭文件的工作留给with open自动完成;
幕后: 使用with语句有一个协议; 通过open语句获取返回的对象, 可以称为thefile; 在开始代码块时, 通常称为thefile.__enter__(), 代码块执行完毕时, 称为thefile.__exit__(); 这样, finally块中的代码被__exit__()自动完成, 有利于避免重复显式地使用try..finally;
<refer to> PEP 343
---TBC---YC