Почему я получаю эту ошибку только при последующем выполнении функции Python?
Я запускаю скрипт Python, который преобразует один тип файла netCDF4 в другой и делает это, вызывая функцию в модуле, который я написал.
Скрипт последовательно обрабатывает несколько файлов. Когда я добираюсь до второго файла в списке, я получаю «IndexError: размер массива данных не соответствует срезу» в «данные ['время'] [:]» в этом фрагменте кода в моей функции:
varobj = cdf.createVariable('time','f8',('time'))
varobj.setncatts(dictifyatts(data['time'],''))
varobj[:] = data['time'][:]
Неважно, что это за файл. Скрипт всегда успешно обрабатывал первый файл, а затем давился вторым, например. во второй раз он вызывает функцию, в которой произошел сбой, в первый раз все в порядке.
Используя отладчик, я обнаружил, что нет никакой разницы в varobj[:] и data['time'][:] от первого до второго вызова. Следующее:
Второй раз, когда функция вызывается, проверка переменных показывает:
ipdb> data['time']
<class 'netCDF4._netCDF4.Variable'>
float64 time(time)
description: time of measurement
calendar: gregorian
units: seconds since 1970-01-01T00:00:00 UTC
path = /Data/Burst
unlimited dimensions:
current shape = (357060,)
filling off
ipdb> varobj
<class 'netCDF4._netCDF4.Variable'>
float64 time(time)
description: time of measurement
calendar: gregorian
units: seconds since 1970-01-01T00:00:00 UTC
unlimited dimensions:
current shape = (357056,)
filling on, default _FillValue of 9.969209968386869e+36 used
При первом вызове функции проверка переменных показывает точно такой же результат с фигурами одинакового размера.
Об этой же ошибке сообщается здесь: Ошибка при создании переменной для создания файл netCDF
И на основе этого я попробовал следующий код:
cf_time = data['time'][:]
cdf.createVariable('time','f8',('time'))
cdf['time'].setncatts(dictifyatts(data['time'],''))
cdf['time'][:] = cf_time[:]
Что тоже не сработало. Та же ошибка при тех же обстоятельствах.
У меня нет идей, и я мог бы использовать предложения о том, что проверить дальше.
Спасибо, Барт, что подсмотрел изменение формы. Это была большая подсказка. Я проверял имена файлов.
Когда я исследовал изменение формы, я обнаружил, что в моей функции одна из входных переменных содержит информацию из предыдущего вызова функции.
Во-первых, почему только одна из входных переменных может хранить устаревшую информацию?
Во-вторых, этого вообще не должно быть, это должно быть за рамками.
Я попытаюсь воспроизвести это поведение в минимизированном коде, а между тем ответы на вопрос о области действия в python будут оценены — я думал, что понял, как python обрабатывает область действия.
Вот минимальный код, который продемонстрирует проблему. Каким-то образом вызывающая функция может изменить переменную (good_ens), которая находится вне области видимости.
def doFile(infileName, outfileName, goodens, timetype, flen):
print('infilename = %s' % infileName)
print('outfilename = %s' % outfileName)
print('goodens at input are from %d to %d' % (goodens[0],goodens[1]))
print('timetype is %s' % timetype)
maxens = flen # fake file length
print('%s time variable has %d ensembles' % (infileName,maxens))
# TODO - goodens[1] has the file size from the previous file run when multiple files are processed!
if goodens[1] < 0:
goodens[1] = maxens
print('goodens adjusted for input file length are from %d to %d' % (goodens[0],goodens[1]))
nens = goodens[1]-goodens[0]
print('creating new netCDF file %s with %d records (should match input file)' % (outfileName, nens))
datapath = ""
datafiles = ['file0.nc',\
'file1.nc',\
'file2.nc',\
'file3.nc']
# fake file lengths for this demonstration
datalengths = [357056, 357086, 357060, 199866]
outfileroot = 'outfile'
attFile = datapath + 'attfile.txt'
# this gets changed! It should never be changed!
# ask for all ensembles in the file
good_ens = [0,-1]
# -------------- beyond here the user should not need to change things
for filenum in range(len(datafiles)):
print('\n--------------\n')
print('Input Parameters before function call')
print(good_ens)
inputFile = datapath + datafiles[filenum]
print(inputFile)
l = datalengths[filenum]
print(l)
outputFile = datapath + ('%s%03d.cdf' % (outfileroot,filenum))
print(outputFile)
print('Converting from %s to %s' % (inputFile,outputFile))
# the variable good_ens gets changed by this calling function, and should not be
doFile(inputFile, outputFile, good_ens, 'CF', l)
# this works, but will not work for me in using this function
#doNortekRawFile(inputFile, outputFile, [0,-1], 'CF', l)