[pyar] Uso eval() para clase definida en otro archivo

Juan Pablo Hernández Vogt jphv.mail en gmail.com
Sab Mar 4 10:32:42 ART 2017


2017-03-03 16:56 GMT-03:00 Marcos Dione <mdione en grulic.org.ar>:

> On Fri, Mar 03, 2017 at 10:26:26AM -0300, Juan Pablo Hernández Vogt wrote:
> > {'passes': [-1, 0, -1, 0], 'DUMMY': True, 'GENERIC_NAME': 'dummy',
> > 'AMBIENT_TEMPERATURE': 293, 'PRESSURE': 1013.25, 'MODE':
> > <CalculationMode.Pass_3D: 1>}
> >
> ...
> >
> > Entonces, cómo hago para que el eval() definido en una clase base sepa
> > sobre tipos definidos en sus clases derivadas?
>
>     yo empezaría no usando eval(), y preguntando: porqué (creés que)
> necesitás eval()? si no tenés control sobre lo que te van a pasar en
> value podes terminar ejecutando codigo arbitrario. muy seguramente hay
> mejores opciones para lo que necesitas.
>

Hola Marcos,

Voy a intentar responder las preguntas:

1) Por qué creo que necesito eval()?
a) Me pareció muy práctico para el contexto de lo que estoy desarrollando,
sobre todo en la etapa de "a ver si puedo hacerlo".

b) Simplemente porque no conocía otra forma de hacerlo. Probé ast que
funciona para tipos simples pero no con clases definidas en otros modulos
(no los conoce) --> aquí es donde eval() y globals() dieron una solucion
simple, aunque peligrosa como mencionan.


2) Conozco que datos van a pasar?
Si, son definiciones de VARIABLE=valor en archivos de texto. A veces
generados por el programa para inspección y también como forma de almacenar
configuraciones de esas variables para que puedan ser utilizadas por el
usuario distintas aplicaciones.

En relación a estos datos y los ejemplos que publiqué, te cuento que es lo
que tengo:
a) Un módulo con la base del framework. Aquí se definen las clases que
permiten crear una cadena de simulaciones y los eslabones de esas cadenas,
de forma general. En este módulo, una clase base común a todas las demás,
tiene los métodos load() y export() de los parámetros.

b) Un módulo específico. Éste implementa los métodos necesarios de los
eslabones de la cadena para unas tareas concretas, además de unos helpers
que le simplifican la vida al usuario para construir complejas secuencias
sin la necesidad de conocer cómo usar los objetos individualmente.
En este módulo hay clases de enumeración (ejemplo: CalculationMode) cuyo
objeto es uno de los parametros de algunas clases.

c) Mi intención primaria era que la lógica de load() en el módulo base
pueda encargarse de convertir el string CalculationMode.Pass_3D en el
objeto enumeración correspondiente. Cómo dicho módulo es el corazón, no
tiene idea de qué define el otro módulo (o incluso otros módulos que se
agreguen en el futuro), fue ahí donde el uso del parametro self.globals,
seteado desde el módulo específico, hizo posible que la clase base
interprete correctamente el string de enumeración.

3) Haciendo desaparecer eval()
Estuve consultando con la almohada y creo saber cómo hacerlo de una manera
mas o menos elegante, pero utilizando *ast *en el caso por default más un
checkeo del string para saber qué objeto devolver (es decir, mi propio
parser del módulo específico).


Gracias chicos por las recomendaciones!
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://listas.python.org.ar/pipermail/pyar/attachments/20170304/748f0280/attachment-0001.html>


Más información sobre la lista de distribución pyar