2010-05-04 10 views
9

Recientemente descubrí el property built-in de Python, que disfraza getters y setters del método de clase como propiedad de una clase. Ahora estoy tentado de usarlo de maneras que estoy bastante seguro de que son inapropiadas.Cuándo utilizar la función "property" incorporada: funciones auxiliares y generadores

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 construcción getX() y setX() que se podría escribir en C++.

¿Pero en qué otro caso es apropiado hacer de una función una propiedad? Por ejemplo, si usted 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 conveniente añadir

vertex_positions = property(get_vertex_positions) 

?

¿Alguna vez se puede hacer que un generador parezca una propiedad? Imagine si un cambio en nuestro código significa que ya no almacenamos Polygon.vertices de la misma manera. ¿Estaría bien entonces agregar esto al Polygon?

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

Respuesta

14
  • Cuando tiene un atributo normal y obtener y/o configurar 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 abstraerse como acceso de atributo, use la propiedad. Si desea que el estado externo (su parcela o sitio web o algo) sea consciente del cambio o si está envolviendo alguna 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 tenga en cuenta

    • Si usted va a hacer cosas como la entrada de higienización para la seguridad o algo importante, explícita 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 que puede encontrar interesante:

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

    • Usted describe lo que property hace como "disfraza getters y setters del método de clase", que no es exactamente el caso. Las cosas que toma property son solo funciones normales, y no necesitan definirse realmente en su clase en absoluto; property pasará self para usted. 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 "método de clase" se refiere a another special thing tipo de propiedades similares que cambian lo que sucede cuando se busca un atributo.

2

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

Así que 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.

Cuestiones relacionadas