@property 和 property() 之间的区别

6

是否存在以下两者之间的区别:

class Example(object):
    def __init__(self, prop):
        self._prop = prop

    def get_prop(self):
        return self._prop

    def set_prop(self, prop):
        self._prop = prop

    prop = property(get_prop, set_prop)

并且

class Example2(object):
    def __init__(self, prop):
        self._prop = prop

    @property
    def prop(self):
        return self._prop

    @prop.setter
    def prop(self, prop):
        self._prop = prop

它们似乎做着相同的事情,这不符合Python只有一种明显方法的目标。是否有一种首选方式?如果是这样,为什么?


1
装饰器只是语法糖而已 - 参见https://dev59.com/fmQm5IYBdhLWcg3wyhjk - dannymilsom
好的,谢谢。有人知道为什么它被添加了吗? - BoshWash
你应该看一下这个PEP。http://legacy.python.org/dev/peps/pep-0318/ - Jayanth Koushik
1
为了让语法更加美观易用,添加了@someDecoratorFunction。就像许多其他东西一样,它只是对其他更复杂的语言结构的语法糖。 - poke
1
@BoshWash:Python 2.4增加了装饰器,Python 2.6增加了property.setter()(以及其兄弟)装饰器。property自2.2版本就已经存在了。 - Martijn Pieters
2个回答

10
< p > @decorator 语法只是一种语法糖。除了语法之外,这两种方法之间没有任何区别,最终结果是相同的。< /p >
@property
def prop(self):
    return self._prop

被翻译为:

def prop(self):
    return self._prop
prop = property(prop)

同样适用于setter:

@prop.setter
def prop(self, prop):
    self._prop = prop

变成:

tmp = prop.setter
def prop(self, prop):
    self._prop = prop
prop = tmp(prop)

装饰器表达式(prop.setter)首先被评估。请参见如何使用@property装饰器?以了解.setter()(以及.deleter().getter())如何工作。

请注意,Python 2.6中才添加了属性对象的prop.setter()装饰器(以及.getter().deleter()装饰器)。此外,property是在Python 2.2中添加的,但装饰器仅在Python 2.4中添加到语言中。

因此,许多文档仍使用旧的property构造方法。

然而,如果您正在为Python 2.6或更新版本编写代码,则应使用装饰器语法。

@property@prop.setter装饰器明确地传达了这里有属性函数的早期视觉信号,而单独的prop = property(...)行在属性函数之后很容易被忽视,特别是如果属性实现较长。


@JayanthKoushik:Python一直具备使用语法以不同方式完成某些事情的能力。列表理解与循环,try:/ finally:用于打开和关闭文件与上下文管理器和 with。新的语法需要一些时间才能成为首选方式,旧的文档仍然存在,等等。这并不意味着Python突然变得不一致或违反原则。 - Martijn Pieters
@BoshWash: “new to be removed”?property()构造函数的签名不会消失,即使在Python 3中也是如此。只是@prop.setter()语法相对较新,需要支持Python 2.4或2.5的代码不能使用它。 - Martijn Pieters
好的,那么它将作为一种不同的表达方式共存,并增加几行代码? - BoshWash
我保证之后会放手,但为什么它更干净呢? - BoshWash
@BoshWash:单独的prop = property(..)行在函数之后,很容易被忽略。@property@prop.setter()语法在每个属性函数之前是更清晰的视觉信号,表明您有属性函数。 - Martijn Pieters
显示剩余2条评论

0

针对您的代码,我在Python 3.7中进行了比较。 输入图像描述

这表明堆栈机器Python字节码将会有一些不同,但几乎相同。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接