property and python

and - Añadiendo dinámicamente @property en python



python class properties (2)

Sé que puedo agregar dinámicamente un método de instancia a un objeto haciendo algo como:

import types def my_method(self): # logic of method # ... # instance is some instance of some class instance.my_method = types.MethodType(my_method, instance)

Más adelante, puedo llamar a instance.my_method() y self se enlazará correctamente y todo funcionará.

Ahora, mi pregunta: ¿cómo hacer exactamente lo mismo para obtener el comportamiento que decoraría el nuevo método con @property?

Supongo que algo como:

instance.my_method = types.MethodType(my_method, instance) instance.my_method = property(instance.my_method)

Pero, al hacer esa instance.my_method , mi instance.my_method devuelve un objeto de propiedad.


Dado que esta pregunta no se refiere solo a la adición a una instancia específica, se puede usar el siguiente método para agregar una propiedad a la clase, esto expondrá las propiedades a todas las instancias de la clase YMMV.

cls = type(my_instance) cls.my_prop = property(lambda self: "hello world") print(my_instance.my_prop) # >>> hello world

Nota: Agregar otra respuesta porque creo que @Alex Martelli, aunque correcta, está logrando el resultado deseado al crear una nueva clase que posee la propiedad, esta respuesta pretende ser más directa / directa sin abstraer lo que sucede en su propio método.


El objeto descriptor de property debe vivir en la clase , no en la instancia , para tener el efecto que desea. Si no desea modificar la clase existente para evitar alterar el comportamiento de otras instancias, deberá crear una "clase por instancia", por ejemplo:

def addprop(inst, name, method): cls = type(inst) if not hasattr(cls, ''__perinstance''): cls = type(cls.__name__, (cls,), {}) cls.__perinstance = True inst.__class__ = cls setattr(cls, name, property(method))

Estoy marcando estas clases especiales "por instancia" con un atributo para evitar hacer innecesariamente varias si estás haciendo varias llamadas addprop en la misma instancia.

Tenga en cuenta que, al igual que para otros usos de la property , necesita que la clase en juego sea de estilo nuevo (que suele obtenerse heredando directa o indirectamente de un object ), no el estilo antiguo heredado (colocado en Python 3) que se asigna de forma predeterminada a un Clase sin bases.