Что делает @property в Django? - PullRequest
       1

Что делает @property в Django?

0 голосов
/ 25 октября 2019

Что такое @property в Django?

Вот как я понимаю: @property - это декоратор для методов в классе, который получает значение в методе.

Но, насколько я понимаю, я могу просто вызвать метод, как обычно, и он получит его. Так что я не уверен, что именно он делает.

Пример из документации:

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)

В чем разница, если она есть, а если нет?

Ответы [ 2 ]

2 голосов
/ 25 октября 2019

Как видите, функция full_name возвращает строку с именами и фамилиями людей.

То, что делает декоратор @property, объявляет, что к нему можно получить доступ, как к обычному свойству.

Это означает, что вы можете вызвать first_name, как если бы это была переменная-член вместо функции, например, так:

name = person.full_name

вместо

name = person.full_name()

Вы также можете определить метод установки следующим образом:

@full_name.setter
def full_name(self, value):
     names = value.split(' ')
     self.first_name = names[0]
     self.last_name = names[1]

Используя этот метод, вы можете установить полное имя человека следующим образом:

person.full_name = 'John Doe'

вместо

person.set_full_name('John Doe')

PS приведенный выше установщик является лишь примером, поскольку он работает только для имен, состоящих из двух слов, разделенных пробелом. В реальной жизни вы бы использовали более надежную функцию.

1 голос
/ 25 октября 2019

В некоторых языках пользователям рекомендуется делать атрибуты приватными и создавать общедоступные методы получения и установки, например, в некоторых составных Python-подобных языках с private и 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_bar

Аргументо предоставлении стабильного интерфейса. Если вы хотите изменить внутреннюю работу вашего класса, например, чтобы найти его в базе данных или вычислить, пользователям класса не придется ничего менять;они просто продолжают вызывать геттер и сеттер.

В Python у нас на самом деле нет личных атрибутов, и нам нужен простой синтаксис. Итак, мы перевернем это: программисты часто напрямую получают доступ к атрибутам объекта. Но что, если вы хотите изменить внутреннее поведение? Мы не хотим менять интерфейс класса.

@property позволяет изменить внутреннюю работу bar без изменения внешнего интерфейса. Пользователи класса могут по-прежнему иметь доступ к foo.bar, но ваша внутренняя логика может быть совершенно другой:

class Foo:
    def __init__(self, bar):
        self.bar = bar

def main():
    f = Foo()
    print(f.bar)

# Later we can change to something 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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...