@property 和 property() 的区别

7 投票
2 回答
1505 浏览
提问于 2025-04-17 22:39

这两段代码有什么区别吗?

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的目标不太一致,因为Python提倡只有一种明显的方法来做事情。那么,有没有更推荐的写法呢?如果有的话,为什么呢?

2 个回答

0

我用Python 3.7对你的代码做了个比较。

从这个比较中可以看出,Python的字节码在栈机器上会有一些小的不同,但基本上是一样的。

10

@decorator 这种写法其实就是一种语法上的简化。除了写法不同,最终的效果是一样的。

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

会被转换成:

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

同样的道理也适用于设置器:

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

变成:

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

因为装饰器表达式(prop.setter)会先被计算。想了解 .setter()(还有 .deleter().getter())是怎么工作的,可以查看 @property 装饰器是怎么工作的?

需要注意的是,prop.setter() 装饰器(还有 .getter().deleter() 装饰器)是在 Python 2.6 版本中才加入的。此外,property 是在 Python 2.2 版本中引入的,但装饰器的功能是在 Python 2.4 中才加入的。

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

不过,如果你是在 Python 2.6 或更新的版本中编程,建议使用装饰器的写法。

@property@prop.setter 装饰器能清晰地提前告诉你这里有属性函数,而如果在属性函数后面单独写 prop = property(...) 这一行,容易被忽略,特别是当属性实现比较长的时候。

撰写回答