Escribí una clase que me permite pasar una lista de tipos de variables, nombres de variables, mensajes y valores predeterminados. La clase crea un panel wxPython, que se muestra en un marco que permite al usuario establecer los valores de entrada antes de presionar el botón de cálculo y obtener los resultados nuevamente como un gráfico. Agrego todas las variables a la clase usando sentencias exec. Esto mantiene todas las variables juntas en una clase, y puedo referirme a ellas por su nombre.

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

Dentro de la clase creo y configuro las variables con declaraciones como:

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() )

Cuando necesito usar las variables, puedo referirme a ellas por su nombre:

 wl = light.wavelength
 n = light.n

Luego leí en SO que rara vez es necesario usar exec en Python. ¿Hay algún problema con este enfoque? ¿Hay una mejor manera de crear una clase que contenga variables que deberían agruparse, que desee poder editar, y que también tenga el código y las llamadas de wxPython para mostrar, editar (y también guardar todas las variables en un archivo o leerlos de nuevo)?

Brusca

1
Curt 17 jul. 2009 a las 21:36

4 respuestas

La mejor respuesta

Puede usar la función setattr, que toma tres argumentos: el objeto, el nombre del atributo y su valor. Por ejemplo,

setattr(self, 'wavelength', wavelength_val)

Es equivalente a:

self.wavelength = wavelength_val

Entonces podrías hacer algo como esto:

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())
18
mipadi 17 jul. 2009 a las 17:40

Para la seguridad consciente, podría haber una alternativa aceptable. Solía haber una llamada de módulo rexec que permitía la ejecución "restringida" de código arbitrario de python. Este módulo se eliminó de las versiones recientes de Python. http://pypi.python.org/pypi/RestrictedPython es otra implementación de la gente de Zope que crea un entorno "restringido" para el código arbitrario de python.

0
kpatvt 28 jul. 2009 a las 01:01

Estoy de acuerdo con la respuesta de mipadi, pero quería agregar una respuesta más, ya que la publicación original preguntó si hay un problema al usar exec. Me gustaría abordar eso.

Piensa como una criminal.

Si su adversario malicioso sabía que tenía un código que decía:

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

Entonces él o ella puede intentar inyectar valores para var_name y var_text_ctrl que piratea su código.

Imagine si un usuario malintencionado pudiera obtener var_name para ser este valor:

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     
"""

De repente, el adversario malicioso pudo hacer que USTED ejecutara el código [ute] para eliminar su directorio / bin (o cualquier maldad que quisieran). Ahora su declaración ejecutiva lee aproximadamente el equivalente de:

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

No buena !!!

Como puede imaginar, es posible construir todo tipo de inyecciones de código malicioso cuando se usa exec. Esto pone la carga sobre el desarrollador al pensar en cualquier forma en que el código pueda ser pirateado, y agrega riesgos innecesarios, cuando hay disponible una alternativa libre de riesgos.

1
BobBob 20 jul. 2009 a las 20:17

El módulo fue eliminado porque tenía problemas de seguridad. Es muy difícil proporcionar un entorno en el que cualquier código se pueda ejecutar en un entorno restringido, con toda la introspección que tiene Python.

Una mejor apuesta es evitar eval y exec.

Una idea realmente descabellada es utilizar Google App Engine y dejar que se preocupen por el código malicioso.

0
BobBob 28 jul. 2009 a las 20:21