[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