2012-10-11 27 views

Respuesta

12

Debe leer los documentos sobre qué descripciones son en realidad. La versión de Cliff's Notes: las descripciones son un mecanismo de bajo nivel que te permite conectar los atributos de un objeto al que se accede. Las propiedades son una aplicación de alto nivel de esto; es decir, las propiedades se implementan usando descriptores. O, mejor aún, las propiedades son descripciones que ya le hemos proporcionado en la biblioteca estándar.

Si necesita una forma simple de devolver un valor calculado a partir de una lectura de atributo, o para llamar a una función en una escritura de atributo, use el decorador @property. El descriptor API es más flexible, pero menos conveniente, y puede decirse que es "exagerado" y no idiomático en esta situación. Es útil para casos de uso más avanzados, como la implementación de métodos enlazados, o métodos estáticos y de clase; cuando necesita saber, por ejemplo, si se accedió al atributo a través del objeto tipo, o una instancia del tipo.

+0

Puede valer la pena señalar que pitón desalienta el uso de captadores y definidores excepto cuando sea necesario ... o puede que no .. –

+3

@JoranBeasley No está tan desanimado como completamente innecesario. Como Python le permite anular el acceso a los atributos, puede decidir si necesita esto en una subclase. Si necesita una propiedad calculada, es apropiado usar un getter. En Java/C#, debe decidir por adelantado si desea permitir anular el acceso a un atributo específico y proporcionarlo en la parte superior de la jerarquía de clases. Es por eso que es común usar propiedades de forma generalizada: se hace "por las dudas". – millimoose

9

Puede leer más sobre ambos desde here. Pero aquí hay un ejemplo simple del mismo libro que trata de explicar la diferencia al resolver lo que esencialmente es el mismo problema. Como puede ver, la implementación que usa propiedades es mucho más simple.

Existen varias formas de acceder a los mecanismos internos de Python para obtener y establecer valores de atributos. La técnica más accesible es usar la función de propiedad para definir los métodos get, set y delete asociados con un nombre de atributo. La función de propiedad crea descriptores para usted. Una técnica ligeramente menos accesible, pero más extensible y reutilizable es definir usted mismo las clases de descriptores. Esto le permite una flexibilidad considerable. Para ello, cree una clase que defina los métodos get, set y delete, y asocie su clase de descriptor con un nombre de atributo.

La función de propiedad nos proporciona una forma práctica de implementar un descriptor simple sin definir una clase separada. En lugar de crear una definición de clase completa, podemos escribir las funciones del método getter y setter, y luego unir estas funciones a un nombre de atributo. ejemplo

descriptor:

ejemplo
class Celsius(object): 
    def __init__(self, value=0.0): 
     self.value= float(value) 
    def __get__(self, instance, owner): 
     return self.value 
    def __set__(self, instance, value): 
     self.value= float(value) 

class Farenheit(object): 
    def __get__(self, instance, owner): 
     return instance.celsius * 9/5 + 32 
    def __set__(self, instance, value): 
     instance.celsius= (float(value)-32) * 5/9 

class Temperature(object): 
    celsius= Celsius() 
    farenheit= Farenheit() 
>>> 
oven= Temperature() 
>>> 
oven.farenheit= 450 
>>> 
oven.celsius 
232.22222222222223 
>>> 
oven.celsius= 175 
>>> 
oven.farenheit 
347.0 

propiedad:

class Temperature(object): 
    def fget(self): 
     return self.celsius * 9/5 + 32 
    def fset(self, value): 
     self.celsius= (float(value)-32) * 5/9 
    farenheit= property(fget, fset) 
    def cset(self, value): 
     self.cTemp= float(value) 
    def cget(self): 
     return self.cTemp 
    celsius= property(cget, cset, doc="Celsius temperature") 
>>> 
oven= Temperature() 
>>> 
oven.farenheit= 450 
>>> 
oven.celsius 
232.22222222222223 
>>> 
oven.celsius= 175 
>>> 
oven.farenheit 
347.0 
+12

Creo que la implementación del descriptor de celsius no es correcta.Debes haber configurado el celsius en 'instance' en lugar de' self'; Si crea dos objetos de temperatura, compartirán el mismo valor celsius. –

+0

Ejecuto el código 'Descriptor example' y funciona bien. Pero no entendí cómo 'instance.celsius' es accesible en la clase' Farenheit'. Gracias. – has