Мы еще вернемся к функции eval далее в этой главе, когда будем исследовать приемы вычисления выражений. Но иногда она оказывается слишком мощным инструментом. Если нет уверенности, что выполняемые таким способом строки не содержат злонамеренный программный код, может потребоваться выполнять их, ограничив доступ к ресурсам компьютера, или использовать более строго инструменты преобразований. Взгляните на следующую версию функции summer (если у вас появится желание поэкспериментировать с ней, вы найдете ее в файле summer2.py в пакете примеров):
def summer(numCols, fileName):
sums = [0] * numCols
for line in open(fileName): # использует итератор файла
cols = line.split(‘,’) # поля разделяются запятыми
nums = [int(x) for x in cols] # ограниченный инстр. преобразования both = zip(sums, nums) # отказ от вложенного цикла for
sums = [x + y for (x, y) in both] # 3.X: zip возвращает итератор return sums
Используя для преобразования строк функцию int, эта версия поддерживает только числа, а не произвольные и, возможно, небезопасные выражения. Первые четыре строки в этой версии напоминают оригинал, однако для разнообразия эта версия исходит из предположения, что данные отделяются запятыми, а не пробельными символами, и использует генератор списков и функцию zip, чтобы избавиться от вложенного цикла for. Кроме того, эта версия существенно сложнее оригинала и по этой причине выглядит менее предпочтительной с точки зрения сопровождения. Если что-то в этом программном коде вам не понятно, попробуйте добавить вызовы функции print после каждой инструкции, чтобы следить за результатами всех операций. Ниже показан результат работы этой функции:
C:\…\PP4E\Lang> type table3.txt
1,5,10,2,1
2,10,20,4,2
3,15,30,8,3
4,20,40,16,4
C:\…\PP4E\Lang> python summer2.py 5 table3.txt
[10, 50, 100, 30, 10]
Использованная литература:
Марк Лутц — Программирование на Python, 4-е издание, II том, 2011