python - 我该怎么做才能让我的程序不因 .fits 文件中不存在的 header 而引发 KeyError?

标签 python keyerror astropy fits pyfits

我正在制作一个程序,该程序在计算机中搜索 .fts 和 .fits 文件,在其中打开文件并检索与 header 中特定关键字相对应的信息,并将文件重命名为该关键字。

我遇到一个问题,因为在文件中找不到我正在搜索的 header 关键字,所以我不断收到 KeyError。有没有解决的办法?我希望能够搜索各种关键字并执行某些操作,即使文件中不存在该关键字。

这里是代码:

from astropy.io import fits
import os

for i in os.listdir(os.getcwd()):
if i.endswith(".fits") or i.endswith(".fts"): 

    hdulist = fits.open(i)

    DATEOBS_header = hdulist[0].header['DATE-OBS'] 
    EXPTIME_header = int(round(hdulist[0].header['EXPTIME']))
    CCDTEMP_header = int(round(hdulist[0].header['CCD-TEMP']))
    XBINNING_header = hdulist[0].header['XBINNING']
    FILTER_header = hdulist[0].header['FILTER']
    IMAGETYP_header = hdulist[0].header['IMAGETYP']
    OBJECT_header = hdulist[0].header['OBJECT']

    DATEandTIME = DATEOBS_header[0:]
    YEAR = DATEandTIME[0:4]
    MONTH = DATEandTIME[5:7]
    DAY = DATEandTIME[8:10]

    #TIME = DATEOBS_header[11:] 
    HOUR = DATEandTIME[11:13]
    MINUTE = DATEandTIME[14:16]
    SECONDS = DATEandTIME[17:]

    DATE = str(YEAR) + str(MONTH) + str(DAY) + 'at' + str(HOUR) + str(MINUTE) + str(SECONDS) 

    if IMAGETYP_header == 'Light Frame':
        newname = str(OBJECT_header) + '_' + str(DATE) + '_' + str(CCDTEMP_header) + 'temp_' + str(XBINNING_header) + 'bin_' + str(EXPTIME_header) + 'exptime_' + str(FILTER_header) + '.fits'

    if IMAGETYP_header == 'Dark Frame':
        newname = 'Dark_' + str(DATE) + 'at' + str(TIME) + '_' + str(CCDTEMP_header) + 'temp_' + str(XBINNING_header) + 'bin_' + str(EXPTIME_header) + 'exptime' + '.fits'

    if IMAGETYP_header == 'Flat Field':
        newname = 'Flat_' + str(DATE) + 'at' + str(TIME) + '_' + str(CCDTEMP_header) + 'temp_' + str(XBINNING_header) + 'bin_' + str(EXPTIME_header) + 'exptime_' + str(FILTER_header) + '.fits'

    prevname = i
    os.rename(prevname, newname)

    hdulist.close()

    continue
else:
    continue

这是我得到的错误:

Traceback (most recent call last):
  File "glo1.py", line 9, in <module>
    DATEOBS_header = hdulist[0].header['DATE-OBS'] 
  File "/home/luisgeesb/.local/lib/python2.7/site-packages/astropy/io/fits/header.py", line 151, in __getitem__
card = self._cards[self._cardindex(key)]
  File "/home/luisgeesb/.local/lib/python2.7/site-packages/astropy/io/fits/header.py", line 1723, in _cardindex
raise KeyError("Keyword %r not found." % keyword)
KeyError: "Keyword 'DATE-OBS' not found."

最佳答案

要防止此类异常停止您的程序,您可以捕获它们,如下所示:

try:
    DATEOBS_header = hdulist[0].header['DATE-OBS']
except KeyError:
    DATEOBS_header = None

或者,使用字典的 .get() 方法,该方法检查键是否存在以及是否不返回默认值,而不是引发异常。返回的默认值为None

如果您这样做,您还需要设置一些合理的默认值,或者捕获您正在转换值的情况(因为您无法转换 None)。

最后,每当您从文件中读取数据时,您都应该始终假设数据格式错误/垃圾,并进行一些防御性编程。在您的代码中,您假设 CCDTEMP 返回的值是一个数字,但如果文件已损坏或有空白怎么办?您的应用程序无法处理这种情况。

下面是一些 try catch 尽可能多的错误的代码:

DATEOBS_header = hdulist[0].header.get('DATE-OBS') 
XBINNING_header = hdulist[0].header.get('XBINNING')
FILTER_header = hdulist[0].header.get('FILTER')
IMAGETYP_header = hdulist[0].header.get('IMAGETYP')
OBJECT_header = hdulist[0].header.get('OBJECT')

# For these two, you need to either set a default
# Here I am setting the default to 0,           ------------v
EXPTIME_header = int(round(hdulist[0].header.get('EXPTIME', 0)))


# Or you need to check for a value :
ccdtemp_value = hdulist[0].header.get('CCD-TEMP')
try:
   ccdtemp_value = int(round(ccdtemp_value))
except ValueError:
   # This means, the value was either None (header does not exist)
   # or it was something that can't be converted to a number
   # since it cannot be converted to a number, we do not know
   # if the value is None or something like an empty string,
   # so we explicitly set the value to None
   ccdtemp_value = None
CCDTEMP_header = ccdtemp_value

关于python - 我该怎么做才能让我的程序不因 .fits 文件中不存在的 header 而引发 KeyError?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36215176/

相关文章:

python - 如何使用 Pandas Merge 函数删除重复的列名

在 Heroku 上安装 Ruby 应用程序 : rake aborted. KeyError: key not found

android - 我如何为 kivy android 安装编译 astropy(使用 numpy)?

python - 我不明白这个KeyError?

python - 遍历 Pandas 系列时出错

python - 使用 astropy.io.fits 编写拟合文件

python - AstroPy距离红移转换精度

python - 使用 tkinter 更改单击时按钮的浮雕

python - 为什么具有相同 'text =' 值的两个输入框被视为相同的输入框?

python - 如何在 django admin 中添加编辑和删除按钮