处理来自 packages/modules 的错误时如何处理 Python 异常

How to handle Python exceptions when dealing with errors from packages/modules

我正在使用一个名为 WCS.all_world2pixastropy 程序包,以便将许多以度为单位的坐标转换为图像上的像素坐标。虽然 运行 这在许多坐标对上,但我最终遇到了一个错误,该错误使我的程序从 运行 停止。这是导致错误的代码,以及错误本身:

import glob
import numpy as np
import re
from astropy.io import fits
from astropy.wcs import WCS

initial_data, centroid_coords = [], []
image_files = glob.glob('/home/username/Desktop/myfolder/*.fits')

for image in image_files:
    img_data = np.nan_to_num(fits.getdata(image))

    obj_num = int(re.search('2\d{6}', image).group(0))
    count_num = int(re.search('_(\d+)_', image).group(1))
    obj_index = int(np.where(good_data == obj_num)[0])
    count_index = int(np.where(np.array(all_counters[obj_index]) == count_num)[0])

    ra, dec = pos_match[obj_index][count_index]
    w = WCS(image)
    x, y = w.all_world2pix(ra, dec, 0)
    initial_data.append(img_data)
    centroid_coords.append((float(x), float(y)))

错误:

x, y = w.all_world2pix(ra, dec, 0)  
  File "/usr/local/anaconda3/lib/python3.6/site-packages/astropy/wcs/wcs.py", line 1827, in all_world2pix
    'input', *args, **kwargs
  File "/usr/local/anaconda3/lib/python3.6/site-packages/astropy/wcs/wcs.py", line 1269, in _array_converter
    return _return_list_of_arrays(axes, origin)
  File "/usr/local/anaconda3/lib/python3.6/site-packages/astropy/wcs/wcs.py", line 1225, in _return_list_of_arrays
    output = func(xy, origin)
  File "/usr/local/anaconda3/lib/python3.6/site-packages/astropy/wcs/wcs.py", line 1826, in <lambda>
    quiet=quiet),
  File "/usr/local/anaconda3/lib/python3.6/site-packages/astropy/wcs/wcs.py", line 1812, in _all_world2pix
    slow_conv=ind, divergent=inddiv)
astropy.wcs.wcs.NoConvergence: 'WCS.all_world2pix' failed to converge to the requested accuracy.
After 2 iterations, the solution is diverging at least for one input point.

我只想跳过那些导致此错误的图像。但我不确定如何将其作为例外处理,因为它不是通常的 Type/Value/SyntaxError,等等...

当它通过我的循环时,when/if 发生了这个错误我只是希望它继续循环中的下一个元素而不为导致错误的元素附加任何内容。我的想法是这样的:

for image in image_files:
    img_data = np.nan_to_num(fits.getdata(image))
    obj_num = int(re.search('2\d{6}', image).group(0))
    count_num = int(re.search('_(\d+)_', image).group(1))
    obj_index = int(np.where(good_data == obj_num)[0])
    count_index = int(np.where(np.array(all_counters[obj_index]) == count_num)[0])

    ra, dec = pos_match[obj_index][count_index]
    w = WCS(image)
    try:
        x, y = w.all_world2pix(ra, dec, 0)
        initial_data.append(img_data)
        centroid_coords.append((float(x), float(y)))    
    except: # skip images where coordinates fail to converge
        # Not sure how to identify the error here
        continue

如何处理这个异常?我以前从未真正处理过这些问题,因此不胜感激。谢谢!

回溯告诉你异常类型,所以你可以直接使用它:

except astropy.wcs.wcs.NoConvergence as ex:
    print(f'file {f} raised {ex!r}, skipping')
    continue

当然,您可能必须导入一些额外的子包或模块才能访问该异常类型。

但是,您真正想要做的是查看文档。大多数设计良好的包都会给你一个你应该看到的异常列表,并且通常有一些你想要捕获的易于访问的超类,而更详细的异常可能是私有的并且可能会发生变化,或者可能 public 但很少需要。

例如,可能有类似 astropy.WcsError 的东西,它是一大堆私有异常类型的子类,包括您看到的 NoConvergence。如果你在文档中看到类似的东西,那就是你应该处理的:

except astropy.WcsError as ex:
    print(f'file {f} raised {ex!r}, skipping')
    continue

你现在所拥有的看起来是可行的。不过,我想为您推荐两个小修改:

  • try 块中包含尽可能少的行数,这样您就不会掩盖意外错误情况
  • 再次捕获特定错误,这样您就不会掩盖意外情况(except 本身会捕获 每个 错误)

for image in image_files:
    < the code you already have, up to the `try` block >

    try:
        x, y = w.all_world2pix(ra, dec, 0)
    except NoConvergence:
        continue

    initial_data.append(img_data)
    centroid_coords.append((float(x), float(y)))    

请注意,您可能还需要为脚本顶部的 NoConvergence 错误添加导入:

from astropy.wcs.wcs import NoConvergence