当前位置: 代码迷 >> 综合 >> 简明Python教程 12)输入输出 13)异常
  详细解决方案

简明Python教程 12)输入输出 13)异常

热度:98   发布时间:2023-12-20 11:12:54.0

第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!
'''
 
= open('poem.txt''w'# open for 'w'riting
f.write(poem) # 文本写入文件
f.close() # 关闭文件
 
= 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
= 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
= 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 1in <module>
    Print('世界你好')
NameError: name 'Print' is not defined

>NameError, 错误信息的打印是错误处理程序完成的;


异常

尝试读取用户的输入, 在中间按ctrl-d:

1
= 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:
    = 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