Python: múltiples propiedades, un setter / getter

Considere las siguientes definiciones de clase

class of2010(object): def __init__(self): self._a = 1 self._b = 2 self._c = 3 def set_a(self,value): print('setting a...') self._a = value def set_b(self,value): print('setting b...') self._b = value def set_c(self,value): print('setting c...') self._c = value a = property(fset=self.set_a) b = property(fset=self.set_b) c = property(fset=self.set_c) 

tenga en cuenta que set_[a|b|c]() hace lo mismo. ¿Hay alguna manera de definir:

 def set_magic(self,value): print('setting ...') self._??? = value 

una vez y utilícelo para a, b, c como sigue

 a = property(fset=self.set_magic) b = property(fset=self.set_magic) c = property(fset=self.set_magic) 

 def attrsetter(attr): def set_any(self, value): setattr(self, attr, value) return set_any a = property(fset=attrsetter('_a')) b = property(fset=attrsetter('_b')) c = property(fset=attrsetter('_c')) 

Veo que sus configuradores simplemente registran un mensaje y luego simplemente asignan el valor; de hecho, su respuesta aceptada simplemente asigna el valor. ¿Está utilizando este patrón porque es la Práctica Aceptada / Sabiduría Convencional en algún otro idioma, tal vez uno cuyo nombre comience con “J”? Si es así, aprenda que el enfoque Pythonic para este mismo diseño es mucho más simple:

 class Of2010(object): def __init__(self): self.a = 1 self.b = 2 self.c = 3 

No hay configuradores de no hacer nada, no se llama a una función intermedia solo para asignar un valor. “¿Que dices? “¿Exposición pública a las variables miembro?” Bueno, , en realidad.

Mira estas clases desde el punto de vista del código del cliente. Para usar su clase, los clientes crean un objeto y luego asignan la propiedad “a” usando:

 obj = Of2010() obj.a = 42 

Notablemente, este es exactamente el mismo código para la clase de 5 líneas que publiqué anteriormente.

¿Por qué el lenguaje J fomenta el estilo de propiedad más detallado? Para preservar la interfaz de clase en caso de futuros cambios en los requisitos. Si en algún momento, algún otro valor del objeto debe cambiar junto con cualquier cambio en a, entonces debe implementar el mecanismo de propiedad. Lamentablemente, el lenguaje J expone la naturaleza del mecanismo de acceso de atributo al código del cliente, de modo que introducir una propiedad en algún momento en el futuro es una tarea de refactorización intrusiva que requerirá una reconstrucción de todos los clientes que hacen uso de esa clase. y su atributo “a”.

En Python, tal no es el caso. El acceso al atributo “a” del objeto se determina en el tiempo de ejecución en la persona que llama. Dado que tanto el acceso directo como el acceso a la propiedad “parecen” lo mismo, su clase Python conserva esta interfaz a pesar de que el mecanismo real es diferente. Lo que importa es que sea idéntico en lo que respecta al código del cliente.

Entonces, en Java, uno introduce esta complejidad de propiedad desde el inicio de esta clase (y de hecho, por Práctica aceptada, de todas las clases), con la remota posibilidad de que pueda ser necesaria algún día en el futuro. Con Python, uno puede comenzar implementando la cosa más simple que podría funcionar, es decir, el acceso directo a las variables miembro simples, dejando el enfoque complejo para el futuro en el que el material adicional es realmente necesario y valioso. Dado que ese día puede que nunca llegue, este es un gran avance para que la primera versión de trabajo de su código salga a la luz.

 class... def __setattr__(self, name, value): print 'setting', name self.__dict__[name] = value 

Eso es.

Puede ser que estés buscando __setattr__(self, name, value)

Mira aqui