property objects define decorators and python properties

python - objects - Cuándo utilizar la propiedad "property": funciones auxiliares y generadores



python get and set attributes (2)

Existe una limitación obvia en el uso de propiedades: no acepta ningún argumento , y nunca lo hará.

Por lo tanto, debe estar seguro de que la función que está transformando en una propiedad nunca se refactorizará en una función con, por ejemplo, argumentos predeterminados adicionales.

Recientemente descubrí la property de Python incorporada , que disfraza getters y setters de clase class como propiedad de una clase. Ahora estoy tentado de usarlo de maneras que estoy bastante seguro de que son inapropiadas.

El uso de la palabra clave property es claramente lo correcto si la clase A tiene una propiedad _x cuyos valores permitidos desea restringir; es decir, reemplazaría la getX() y setX() uno podría escribir en C ++.

Pero, ¿en qué otro lugar es apropiado hacer de una función una propiedad? Por ejemplo, si tiene

class Vertex(object): def __init__(self): self.x = 0.0 self.y = 1.0 class Polygon(object): def __init__(self, list_of_vertices): self.vertices = list_of_vertices def get_vertex_positions(self): return zip( *( (v.x,v.y) for v in self.vertices ) )

es apropiado agregar

vertex_positions = property( get_vertex_positions )

?

¿Está bien hacer que un generador se vea como una propiedad? Imagine si un cambio en nuestro código significa que ya no almacenamos Polygon.vertices la misma manera. ¿Estaría bien entonces agregar esto a Polygon ?

@property def vertices(self): for v in self._new_v_thing: yield v.calculate_equivalent_vertex()


  • Cuando tiene un atributo normal y obtener y / o configurarlo tiene sentido para el usuario de una clase, exponer el atributo directamente. Una gran razón por la que los miembros públicos son anatema en algunos idiomas es que si necesita hacer algo más complejo más adelante, necesitaría un cambio de API; en Python puedes simplemente definir una propiedad.

  • Si está utilizando algo que debe abstraer como acceso de atributo, use propiedad. Si desea que el estado externo (su parcela o sitio web o algo) sea consciente del cambio o si está envolviendo una biblioteca que usa miembros directamente, las propiedades podrían ser el camino a seguir.

  • Si algo no es atributo-y, no lo convierta en una propiedad. No hay ningún problema al hacer un método, y puede ser ventajoso: lo que hace es más obvio, puede pasar algún método enlazado si lo necesita, puede agregar argumentos clave sin un cambio de API.

    Es difícil imaginar una situación en la que usaría una función de generador como propiedad. La única forma de tener un atributo normal que se comporte de manera similar requeriría mucha complejidad, por lo que ese caso no recuerda mucho al acceso a los atributos.

  • Usted señala que puede usar property para restringir el acceso a algún atributo interno _x . Esto puede ser cierto, pero ten en cuenta

    • Si va a hacer cosas como la entrada de desinfección para seguridad o algo importante, explícito es mejor que implícito . No desea sentir que el código funciona solo cuando se trata de tales cosas, porque entonces se encontrará con un código que no funciona.

    • A veces las personas usan property para implementar atributos de solo lectura. Por lo general, es mejor tener un atributo normal y darse cuenta de que no se puede evitar que un usuario haga algo tonto y sin apoyo.

  • Nitpicking puede resultarle interesante:

    • property no es una palabra clave; es un nombre normal que puedes volver a vincular. Esto es algo interesante ya que la property no es una cosa de sintaxis ni nada: es una clase normal que podrías implementar tú mismo en Python puro. Utiliza el mismo mecanismo que hace que los métodos funcionen en los descriptores de Python.

    • Usted describe qué hace la property como "disfraza getters y setters del método de clase", que no es exactamente el caso. Las cosas que toman las property son solo funciones normales, y no necesitan definirse realmente en su clase en absoluto; property pasará por ti. Las funciones no se convierten en métodos hasta que las busca, cuando Python crea objetos de método sobre la marcha. Durante la definición de la clase, son solo funciones. Cuando tienes un método normal se llama un "método de instancia"; en Python, el "método de clase" se refiere a otro tipo especial de propiedades similares que cambia lo que sucede cuando se busca un atributo.