Использование Eval в Python для создания переменных класса - PullRequest
1 голос
/ 17 июля 2009

Я написал класс, который позволяет мне передавать список типов переменных, имен переменных, приглашений и значений по умолчанию. Класс создает панель 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

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

Curt

Ответы [ 4 ]

18 голосов
/ 17 июля 2009

Вы можете использовать функцию 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())
1 голос
/ 21 июля 2009

Я согласен с ответом mipadi, но хотел добавить еще один ответ, поскольку в исходном сообщении спрашивалось, есть ли проблемы с использованием 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 можно создавать всевозможные инъекции вредоносного кода. Это накладывает на разработчика бремя думать о любом способе взлома кода и добавляет ненужный риск, когда доступна безрисковая альтернатива.

0 голосов
/ 29 июля 2009

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

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

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

0 голосов
/ 28 июля 2009

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

...