¿Qué es @property en Django?
Así es como lo entiendo: @property es un decorador de métodos en una clase que obtiene el valor en el método.
Pero, según tengo entendido, puedo simplemente llamar al método como de costumbre y lo obtendrá. Así que no estoy seguro de qué hace exactamente.
Ejemplo de los documentos :
from django.db import models class Person(models.Model): first_name = models.CharField(max_length=50) last_name = models.CharField(max_length=50) birth_date = models.DateField() def baby_boomer_status(self): "Returns the person's baby-boomer status." import datetime if self.birth_date < datetime.date(1945, 8, 1): return "Pre-boomer" elif self.birth_date < datetime.date(1965, 1, 1): return "Baby boomer" else: return "Post-boomer" @property def full_name(self): "Returns the person's full name." return '%s %s' % (self.first_name, self.last_name)¿Cuál es la diferencia entre si está y si no está?
Como puede ver, la función full_name devuelve una cadena con el nombre y apellido de las personas.
Lo que hace el decorador @property es declarar que se puede acceder a ella como si fuera una propiedad normal.
Esto significa que puede llamar a full_name como si fuera una variable miembro en lugar de una función, así:
name = person.full_name
en lugar de
name = person.full_name()
También podría definir un método setter como este:
@full_name.setter def full_name(self, value): names = value.split(' ') self.first_name = names[0] self.last_name = names[1]Con este método, puede establecer el nombre completo de una persona de esta manera:
person.full_name = 'John Doe'en lugar de
person.set_full_name('John Doe')PD: el setter anterior es solo un ejemplo, ya que solo funciona para nombres que consisten en dos palabras separadas por un espacio en blanco. En la vida real, usaría una función más robusta.
En algunos idiomas, se alienta a los usuarios a hacer que los atributos sean privados y crear métodos públicos de obtención y establecimiento, por ejemplo, en algunos lenguajes inventados similares a Python con private y public :
class Foo: private bar public get_bar(bar): return self.bar # or look it up in a database # or compute it on the fly from other values # or anything else public set_bar(new_bar): self.bar = new_barEl argumento es sobre proporcionar una interfaz estable. Si desea cambiar el funcionamiento interno de su clase, por ejemplo, buscarlo en una base de datos o calcularlo, los usuarios de la clase no tendrán que cambiar nada; simplemente siguen llamando al getter y setter.
En Python realmente no tenemos atributos privados y queremos una sintaxis simple. Así que le damos la vuelta: los programadores a menudo acceden directamente a los atributos de un objeto. Pero, ¿y si quieres cambiar el comportamiento interno? No queremos cambiar la interfaz de la clase.
@property le permite cambiar el funcionamiento interno de la bar sin cambiar la interfaz externa. Los usuarios de la clase aún pueden acceder a foo.bar , pero su lógica interna puede ser completamente diferente:
class Foo: def __init__(self, bar): self.bar = bar def main(): f = Foo() print(f.bar) # Later we can change to something like this without breaking other code class Foo: def __init__(self, bar): self.save_bar_to_database(bar) # Or anything else @property def bar(self): return self.load_bar_from_database()