¿Puedo crear propiedades de clase durante __new__ o __init__?
Quiero hacer algo como esto, pero hasta ahora no he tenido mucho éxito. Me gustaría hacer de cada atributo una propiedad que calcule _lazy_eval solo cuando se accede a ella:
class Base(object):
def __init__(self):
for attr in self._myattrs:
setattr(self, attr, property(lambda self: self._lazy_eval(attr)))
def _lazy_eval(self, attr):
#Do complex stuff here
return attr
class Child(Base):
_myattrs = ['foo', 'bar']
me = Child()
print me.foo
print me.bar
#desired output:
#"foo"
#"bar"
** ACTUALIZACIÓN **
Esto tampoco funciona:
class Base(object):
def __new__(cls):
for attr in cls._myattrs:
setattr(cls, attr, property(lambda self: self._lazy_eval(attr)))
return object.__new__(cls)
#Actual output (it sets both .foo and .bar equal to "bar"??)
#bar
#bar
** ACTUALIZACIÓN 2 **
Usé la__metaclass__
solución, pero lo metí enBase.__new__
en lugar. Parece que necesitaba un cierre mejor definido - "prop ()" - para formar la propiedad correctamente:
class Base(object):
def __new__(cls):
def prop(x):
return property(lambda self: self._lazy_eval(x))
for attr in cls._myattrs:
setattr(cls, attr, prop(attr))
return object.__new__(cls)
#Actual output! It works!
#foo
#bar