Использование Eval в Python для создания переменных класса

StackOverflow https://stackoverflow.com/questions/1144702

Вопрос

Я написал класс, который позволяет мне передавать список типов переменных, имен переменных, подсказок и значений по умолчанию.Класс создает панель wxPython, которая отображается во фрейме, позволяющем пользователю устанавливать входные значения перед нажатием кнопки рассчитать и получением результатов обратно в виде графика.Я добавляю все переменные в класс, используя инструкции exec .Это позволяет объединить все переменные в одном классе, и я могу ссылаться на них по имени.

light = Variables( frame , [ ['f','wavelength','Wavelength (nm)',632.8] ,\
                             ['f','n','Index of Refraction',1.0],])

Внутри класса я создаю и устанавливаю переменные со статментами типа:

for variable in self.variable_list:
       var_type,var_text_ctrl,var_name = variable
       if var_type == 'f' :  
           exec( 'self.' + var_name + ' = ' + var_text_ctrl.GetValue() )

Когда мне нужно использовать переменные, я могу просто ссылаться на них по имени:

 wl = light.wavelength
 n = light.n

Затем я читаю дальше, так что редко возникает необходимость использовать exec в Python.Есть ли проблема с таким подходом?Есть ли лучший способ создать класс, который содержит переменные, которые следует сгруппировать вместе, которые вы хотите иметь возможность редактировать, а также имеет вызовы code и wxPython для отображения, редактирования (а также сохранения всех переменных в файл или их повторного чтения)?

Курт

Это было полезно?

Решение

Вы можете использовать setattr функция, которая принимает три аргумента:объект, имя атрибута и его значение.Например,

setattr(self, 'wavelength', wavelength_val)

эквивалентно:

self.wavelength = wavelength_val

Итак, вы могли бы сделать что-то вроде этого:

for variable in self.variable_list:
       var_type,var_text_ctrl,var_name = variable
       if var_type == 'f' :
           setattr(self, var_name, var_text_ctrl.GetValue())

Другие советы

Я согласен с ответом мипади, но хотел добавить еще один ответ, поскольку в Исходном сообщении спрашивалось, есть ли проблема с использованием exec.Я хотел бы обратиться к этому вопросу.

Думай как преступник.

Если бы ваш злонамеренный противник знал, что у вас есть код, который гласит:

exec( 'self.' + var_name + ' = ' + var_text_ctrl.GetValue() )

затем он или она может попытаться ввести значения для var_name и var_text_ctrl, которые взломают ваш код.

Представьте, мог бы злоумышленник присвоить var_name это значение:

var_name = """
a = 1                 #  some bogus assignment to complete "self." statement
import os             #  malicious code starts here
os.rmdir('/bin')      #  do some evil
                      #  end it with another var_name 
                      #  ("a" alone, on the next line)
a     
"""

Внезапно злоумышленник смог заставить ВАС выполнить [ute] код для удаления вашего каталога / bin (или любого другого зла, которое они хотят).Теперь ваше заявление exec примерно соответствует эквиваленту:

exec ("self.a=1 \n import os \n os.rmdir('/bin') \n\n "
             "a" + ' = ' + var_text_ctrl.GetValue() ) 

нехорошо!!!

Как вы можете себе представить, при использовании exec возможно создавать всевозможные инъекции вредоносного кода.Это возлагает на разработчика обязанность думать о любом способе взлома кода - и добавляет ненужный риск, когда доступна безрисковая альтернатива.

Для тех, кто заботится о безопасности, может существовать приемлемая альтернатива.Раньше существовал модуль вызова rexec, который допускал "ограниченное" выполнение произвольного кода python.Этот модуль был удален из последних версий python. http://pypi.python.org/pypi/RestrictedPython это еще одна реализация сотрудников Zope, которая создает "ограниченную" среду для произвольного кода python.

Модуль был удален из-за проблем с безопасностью.Очень сложно обеспечить среду, в которой любой код может быть выполнен в ограниченной среде, со всем тем самоанализом, который есть у Python.

Лучше всего избегать eval и exec .

Действительно нестандартная идея - использовать Google App Engine и позволить им беспокоиться о вредоносном коде.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top