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

Daniel dmlistapython en gmail.com
Mar Mar 7 16:18:52 ART 2017


El 3 de marzo de 2017, 16:53, Juan Pablo Hernández Vogt <jphv.mail en gmail.com
> escribió:

> Si Carlos, está usando el entorno del archivo base.py
>
> Este concepto de entorno es nuevo para mi, que en otros lenguajes no está
> presente de esta manera.
>
> Finalmente puedo decir que hice un arreglo bastante simple gracias a que
> todas las clases del archivo derived.py heredan de una clase común --> los
> herederos setean el entorno que debe usarse.
>
> Nota: no utilizo herencia múltiple.
>
> Paso a documentar cómo se resolvió el caso:
>
> *File: base.py*
> class BaseObject(object):
>     def __init__(self, parameters=None):
>         self.parameters = parameters
>
>         # Derived classes from other files must set its environment
>         # in order to be able to execute eval() correctly.
>         self.globals = None
>
>     def load_parameter(self, key, value):
>         if not self.parameters:
>             self.parameters = {}
>
>         self.parameters[key] = eval(value, self.globals)
>
>
> *File: derived.py*
> from base import *
>
> # Using aenum from: pip install aenum
> from aenum import Enum
>
> class CalculationMode(Enum):
>     Pass_2D = 0
>     Pass_3D = 1
>
>
> class Derived(BaseObject):
>     def __init__(self, parameters=None):
>         super(Derived, self).__init__(parameters)
>         self.globals = globals()
>
>
> class Child(Derived):
>     def __init__(self, parameters=None):
>         super(Child, self).__init__(parameters)
>
>
> if __name__ == "__main__":
>
>     obj = Child()
>
>     obj.load_parameter('GENERIC_NAME', '"dummy"')
>     obj.load_parameter('AMBIENT_TEMPERATURE', '293')
>     obj.load_parameter('PRESSURE', '1013.25')
>     obj.load_parameter('DUMMY', 'True')
>     obj.load_parameter('passes', '[-1, 0, -1, 0]')
>
>     print(obj.parameters)
>
>     print("load enumeration")
>     obj.load_parameter('MODE', 'CalculationMode.Pass_3D')
>     print(obj.parameters)
>
>
> Gracias por dale una mirada a este caso.
>
> Saludos!
>
> El 3 de marzo de 2017, 13:56, Carlos Matías <cmdelatorre en gmail.com>
> escribió:
>
>> Fijate si no te queda clara la doc de eval https://docs.python.org/3/libr
>> ary/functions.html#eval
>>
>> ...If both dictionaries are omitted [globals and locals], the expression
>>> is executed in the environment where eval() is called.
>>>
>>
>> Entonces me parece que se está usando el entorno del archivo *base.py*,
>> en el que no está definido CalculationMode.
>>
>> ¿Puede ser?
>>
>>
>>
>> Carlos Matías
>> @py_litox <https://twitter.com/py_litox>
>>
>> 2017-03-03 10:26 GMT-03:00 Juan Pablo Hernández Vogt <jphv.mail en gmail.com
>> >:
>>
>>> Buenos días gente,
>>>
>>> Como todo nuevo en Python tengo un problema al usar eval() que no
>>> entiendo. Parece que hay algo relacionado al evironment en el que es
>>> ejecutado.
>>>
>>> Aquí un ejemplo mínimo que arroja el siguiente error:
>>>
>>> *NameError: name 'CalculationMode' is not defined*
>>>
>>>
>>> Si muevo la definicion de la clase *CalculationMode *a *base.py*,
>>> eval() funcionará correctamente:
>>>
>>> {'passes': [-1, 0, -1, 0], 'DUMMY': True, 'GENERIC_NAME': 'dummy',
>>> 'AMBIENT_TEMPERATURE': 293, 'PRESSURE': 1013.25, 'MODE':
>>> <CalculationMode.Pass_3D: 1>}
>>>
>>>
>>> *File: base.py*
>>> class BaseObject(object):
>>>     def __init__(self, parameters=None):
>>>         self.parameters = parameters
>>>
>>>     def load_parameter(self, key, value):
>>>         if self.parameters is None:
>>>             self.parameters = {}
>>>
>>>         self.parameters[key] = eval(value)
>>>
>>>
>>> *File: derived.py*
>>> from base import *
>>>
>>> # Using aenum from: https://pypi.python.org/pypi/aenum/1.4.5
>>> from aenum import Enum
>>>
>>> class CalculationMode(Enum):
>>>     Pass_2D = 0
>>>     Pass_3D = 1
>>>
>>>
>>> class Derived(BaseObject):
>>>     def __init__(self, parameters=None):
>>>         super(Derived, self).__init__(parameters)
>>>
>>>
>>> if __name__ == "__main__":
>>>
>>>     obj = Derived()
>>>
>>>     obj.load_parameter('GENERIC_NAME', '"dummy"')
>>>     obj.load_parameter('AMBIENT_TEMPERATURE', '293')
>>>     obj.load_parameter('PRESSURE', '1013.25')
>>>     obj.load_parameter('DUMMY', 'True')
>>>     obj.load_parameter('passes', '[-1, 0, -1, 0]')
>>>
>>>     print(obj.parameters)
>>>
>>>     print("load enumeration")
>>>     obj.load_parameter('MODE', 'CalculationMode.Pass_3D')
>>>     print(obj.parameters)
>>>
>>>
>>> Entonces, cómo hago para que el eval() definido en una clase base sepa
>>> sobre tipos definidos en sus clases derivadas?
>>>
>>> Se puede hacer de forma simple o se debe pasar un "contexto" como
>>> parámetro?
>>>
>>>
>>> Gracias por su tiempo!
>>>
>>> _______________________________________________
>>> pyar mailing list pyar en python.org.ar
>>> http://listas.python.org.ar/listinfo/pyar
>>>
>>> PyAr - Python Argentina - Sitio web: http://www.python.org.ar/
>>>
>>> La lista de PyAr esta Hosteada en USLA - Usuarios de Software Libre de
>>> Argentina - http://www.usla.org.ar
>>>
>>
>>
>> _______________________________________________
>> pyar mailing list pyar en python.org.ar
>> http://listas.python.org.ar/listinfo/pyar
>>
>> PyAr - Python Argentina - Sitio web: http://www.python.org.ar/
>>
>> La lista de PyAr esta Hosteada en USLA - Usuarios de Software Libre de
>> Argentina - http://www.usla.org.ar
>>
>
>
> _______________________________________________
> pyar mailing list pyar en python.org.ar
> http://listas.python.org.ar/listinfo/pyar
>
> PyAr - Python Argentina - Sitio web: http://www.python.org.ar/
>
> La lista de PyAr esta Hosteada en USLA - Usuarios de Software Libre de
> Argentina - http://www.usla.org.ar
>

CalculationMode es una clase, pero no estoy viendo donde está instanciada
la clase
me parece que estás queriendo acceder a un parámetro de la clase que no
esta instanciada
(no le pude dedicar mucho tiempo a leer el código, simplemente golpe de
vista, así que tal vez digo una ganzada)
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://listas.python.org.ar/pipermail/pyar/attachments/20170307/3e203f1e/attachment.html>


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