Django 的@property 有什么作用?

Jor*_*dan 47 python django

什么是@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)
Run Code Online (Sandbox Code Playgroud)

如果存在与不存在有什么区别?

Nic*_*oen 61

如您所见,该函数full_name返回一个包含人名和姓氏的字符串。

什么@property装饰呢,就是声明它可以访问就像是一个普通的属性。

这意味着您可以full_name像调用成员变量而不是函数一样调用它,如下所示:

name = person.full_name

代替

name = person.full_name()

你也可以像这样定义一个 setter 方法:

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

使用这种方法,您可以像这样设置一个人的全名:

person.full_name = 'John Doe'
Run Code Online (Sandbox Code Playgroud)

代替

person.set_full_name('John Doe')
Run Code Online (Sandbox Code Playgroud)

PS 上面的 setter 只是一个例子,因为它只适用于由空格分隔的两个单词组成的名称。在现实生活中,您会使用更强大的函数。


Chr*_*ris 7

在某些语言的用户被鼓励属性私下和一些由创建公共getter和setter方法,例如Python的语言一样用privatepublic

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
Run Code Online (Sandbox Code Playgroud)

争论是关于提供一个稳定的接口。如果您想更改类的内部工作方式,例如从数据库中查找或计算它,则类的用户无需更改任何内容;他们只是不断地调用 getter 和 setter。

在 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 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()
Run Code Online (Sandbox Code Playgroud)