2016-03-25 39 views
2

我正在製作一個程序,用於在計算機上搜索.fts和.fits文件,在該文件中打開文件並檢索與標題中特定關鍵字相對應的信息,並將該文件重命名爲該關鍵字。我可以爲我的程序做些什麼,不要爲不存在於.fits文件中的標題拋出KeyError?

我有一個問題,我不斷收到一個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." 
+1

這聽起來像你需要執行一些異常處理 –

+3

https://docs.python.org/3.5/tutorial/errors .html#handling-exceptions – Evert

+0

您也可以使用類似'DATEOBS_header = hdulist [0] .header.get('DATE-OBS',some_default_value')的默認值''。 – Evert

回答

4

爲了防止這些類型的異常從停止你的程序,你可以抓住他們,就像這樣:

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

或者,使用字典的.get()方法,檢查是否有鍵存在,如果它不't返回一個默認值,而不是引發異常。返回的默認值是None

如果你這樣做,你還需要設置一些合理的默認值,或者捕捉那些你正在投射值的情況(因爲你不能投射None)。

最後,無論何時您正在從文件中讀取數據,您都應該假設數據格式不正確/垃圾並執行一些防禦性編程。在你的代碼中,你假設爲CCDTEMP返回的值是一個數字,但是如果該文件已損壞或空白,該怎麼辦?你的應用程序不處理這種情況。

下面是一些代碼,試圖捕捉儘可能多的錯誤,儘可能:

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 
+0

當我設置一個默認值時,看起來很棒 –

+0

,如果找不到關鍵字,它會返回默認值嗎?例如,在上面的代碼中,如果未找到CCD-TEMP,它會顯示'ccdtemp_value = hdulist [0] .header.get('CCD-TEMP')',它將返回0? –

+0

如果找不到密鑰的默認返回值是'None',所以如果您希望它爲零,則需要將其傳入,如下所示:ccdtemp_value = hdulist [0] .header.get('CCD- TEMP',0)' –

0

假設hdulist[0].header給你一個dict例如,你可以這樣做

DATEOBS_header = hdulist[0].header.get('DATE-OBS') 

哪如果密鑰將返回不存在。

有關更多詳細信息,請參閱https://docs.python.org/2/library/stdtypes.html#dict.get

+1

'hdulist [0] .header'不是字典或字典子類,但它的行爲類似。 – Evert

相關問題