python:try语句内部崩溃,预期会发生什么?

时间:2018-07-16 16:25:20

标签: python exception-handling

我过去也遇到过类似的问题,python的try语句中崩溃了。代码失败,因为它试图打开的文件或目录都不存在。但是因为它在try语句中,所以我不明白为什么代码会中断。

{为了避免任何读者花太多时间试图理解代码的前提。它正在尝试从以下位置查找区域文件的顶点:

a)主文件,如果不存在或损坏,请尝试(b)

b)特定于其名称的文件,如果该文件不存在或损坏,则执行(c)

c)创建一个新的 }

p.s。以下代码不够精巧,可能不会成为即时解决方案的最终解决方案。

    try:
        x1,y1, x2,y2 = np.loadtxt('regions/master.reg')
        plt.plot([x1,x1,x2,x2,x1],[y1,y2,y2,y1,y1], c='k')
        plt.draw()
        if (raw_input('Master Acceptable? (y/n): ') =='n'): raise(NameError)
    except NameError:
        try:
            x1,y1, x2,y2 = np.loadtxt('regions/'+self.name[:-5]+'.reg')
            plt.plot([x1,x1,x2,x2,x1],[y1,y2,y2,y1,y1], c='r')
            plt.draw()
            if raw_input('Reg Acceptable? (y/n): ') =='n': raise(NameError)

        except NameError:
            quality = False
            while not quality:
                x1=int(input('x, top left: '))
                y1=int(input('y, top right: '))
                x2=int(input('x, bottom left: '))
                y2=int(input('y, bottom right: '))
                plt.plot([x1,x1,x2,x2,x1],[y1,y2,y2,y1,y1], c='r')
                plt.draw()
                if raw_input('Acceptable? (y/n): ') =='y': quality=True

错误(只是说文件不存在)

File "pre_science.py", line 45, in crop
  x1,y1, x2,y2 = np.loadtxt('regions/master.reg')
File "/usr/local/lib/python2.7/dist-packages/numpy/lib/npyio.py", line 917, in loadtxt
  fh = np.lib._datasource.open(fname, 'rt', encoding=encoding)
File "/usr/local/lib/python2.7/dist-packages/numpy/lib/_datasource.py", line 260, in open
  return ds.open(path, mode, encoding=encoding, newline=newline)
File "/usr/local/lib/python2.7/dist-packages/numpy/lib/_datasource.py", line 616, in open
  raise IOError("%s not found." % path)
IOError: regions/master.reg not found.

所以我的问题是,这是预期的行为吗?

3 个答案:

答案 0 :(得分:1)

您在try-except块中指定了期望的 NameError ,但得到的是 IOError

使用

try:
    ....
except NameError:
    ....

您仅处理 NameError 类型的异常。抛出的所有其他异常(在您的情况下为 IOError )不会在任何地方处理,从而使您的代码崩溃。

删除期望后的 NameError 或按以下方式添加其他期望的错误

try:
    ....
expect NameError, IOError:
    ....

答案 1 :(得分:0)

您正试图仅捕获NameError。使其同时捕获IOError和NameError

try:
    ...
    ...
except (IOError, NameError):
    ...
    ...

答案 2 :(得分:0)

NameError是错误的异常类型,请使用OSError

try:
    x1,y1, x2,y2 = np.loadtxt('regions/master.reg')
    plt.plot([x1,x1,x2,x2,x1],[y1,y2,y2,y1,y1], c='k')
    plt.draw()
    if raw_input('Master Acceptable? (y/n): ') =='n': raise OSError()
except OSError:
    try:
        x1,y1, x2,y2 = np.loadtxt('regions/'+self.name[:-5]+'.reg')
        plt.plot([x1,x1,x2,x2,x1],[y1,y2,y2,y1,y1], c='r')
        plt.draw()
        if raw_input('Reg Acceptable? (y/n): ') =='n': raise OSError()
    except OSError:
        while True:
            x1=int(input('x, top left: '))
            y1=int(input('y, top right: '))
            x2=int(input('x, bottom left: '))
            y2=int(input('y, bottom right: '))
            plt.plot([x1,x1,x2,x2,x1],[y1,y2,y2,y1,y1], c='r')
            plt.draw()
            if raw_input('Acceptable? (y/n): ') =='y':
                break

通常,NameError不应用作用户生成的异常,因为NameError几乎总是表示编程错误。

本着“不要重复自己”的精神,重组后的代码看起来像这样:

from functools import partial
from itertools import cycle, chain

def input_rect():
    x1 = int(raw_input('x, top left: '))
    y1 = int(raw_input('y, top right: '))
    x2 = int(raw_input('x, bottom left: '))
    y2 = int(raw_input('y, bottom right: '))

for reader in chain([
        partial(np.loadtxt, 'regions/master.reg'),
        partial(np.loadtxt, 'regions/'+self.name[:-5]+'.reg'),
    ], cycle([input_rect]))
    try:
        x1, y1, x2, y2 = reader()
    except (ValueError, OSError):
        pass
    else:
        plt.plot([x1,x1,x2,x2,x1],[y1,y2,y2,y1,y1], c='r')
        plt.draw()
        if raw_input('Acceptable? (y/n): ') == 'y':
            break