A la pregunta:descriptores como atributos ejemplo en Python
Por qué no puede ser descriptores atribuye ejemplo?
ha sido answered que:
objetos descriptor tiene que vivir en la clase, no en la instancia
porque esa es la forma en que el __getattribute__
se implementa.
Un ejemplo simple. Considere un descriptor:
class Prop(object):
def __get__(self, obj, objtype=None):
if obj is None:
return self
return obj._value * obj._multiplier
def __set__(self, obj, value):
if obj is None:
return self
obj._value = value
class Obj(object):
val = Prop()
def __init__(self):
self._value = 1
self._multiplier = 0
considerar el caso en el que cada obj tiene múltiples Prop: yo tendría que usar nombres únicos para identificar los valores y los multiplicadores (como here Tener un objeto descriptor por cada instancia permitiría almacenar el. . _multiplier
(y el _value
) en el descriptor de sí mismo, lo que simplifica algunas cosas
para implementar por ejemplo descriptor de atributos que necesita para cualquiera:
Soy consciente de que preguntas similares se han planteado antes, pero no he encontrado una explicación real:
- Por qué Python está diseñado de esta manera?
- ¿Cuál es la forma sugerida de almacenar la información que el descriptor necesita pero es por instancia?
Puedes expandir lo que quieres decir con ** romper orientación de objeto **. En segundo lugar, el problema que veo con este enfoque es cómo proporcionar una API simple para cambiar el multiplicador. Los usuarios tendrán que hacer algo como 'obj._multiplier [Obj.val] = 10'. Esto se puede envolver en una función 'def change_multiplier (self, attr_name, new_value)' pero no escala bien si 'Prop' tiene múltiples atributos. Algo como 'def prop (self, attr_name): return self.__dict __ [attr_name] 'podría usarse para hacer algo como' obj.prop ('val'). multiplicador = 10'. – Hernan
@Hernan hay una suposición habitual de que las instancias tienen el mismo tipo; viola eso y varias cosas se romperán. En lo que se refiere a cambiar el multiplicador, ¿quizás una propiedad proxy? - ver editar arriba. – ecatmur
Es cierto que todas las instancias no serán del mismo tipo, pero puede crear subclases, por lo que la instancia seguirá funcionando. En cuanto al proxy, escribí algo como esto, pero no estoy seguro de que sea una buena idea. Básicamente, 'obj.prop ('val')' devuelve un objeto proxy que conoce acerca de 'obj' y' val'. Cuando haces 'obj.prop ('val'). Multiplicador = 10' escribe a' obj._multiplier [val] = 10'. No estoy seguro de lo fácil que será. – Hernan