使用property()和@property定义的属性

时间:2016-10-12 16:45:33

标签: python oop

我现在正在努力学习Python,我真的很困惑有两种创建对象属性的方法:使用@property装饰器和property()方法。所以以下两个都是有效的:

class MyClassAt:
    def __init__(self, value):
        self._time = value

    @property
    def time(self):
        return self._time

    @time.setter
    def time(self, value):
        if value > 0:
            self._time = value
        else:
            raise ValueError('Time should be positive')

class MyClassNoAt:
    def __init__(self, value):
        self._time = value

    def get_time(self):
        return self._time

    def set_time(self, value):
        if value > 0:
            self._time = value
        else:
            raise ValueError('Time should be positive')

    time = property(fget=get_time, fset=set_time)

是否有使用哪个协议? Pythonista会选择什么?

2 个答案:

答案 0 :(得分:2)

它们是等价的,但第一个是首选,因为许多人发现它更具可读性(同时也不会使代码命名空间混乱)。 第二种方法的问题是你定义了两种你永远不会使用的方法,它们仍然存在于类中。

只有在必须支持非常旧的Python版本时才会使用第二种方法,这种版本不支持装饰器语法糖。函数和方法装饰器在Python 2.4中添加(而类装饰器仅在版本2.6中),因此几乎在所有情况下都是过去的问题。

答案 1 :(得分:1)

在过去(pre python 2.4)中,装饰器语法(即@property)尚不存在,因此创建装饰函数的唯一方法是使用第二种方法

time = property(fget=get_time, fset=set_time)

PEP that lead to decorators给出了更新语法背后的动机的许多原因,但也许最重要的是这一个。

  

将转换应用于函数或的当前方法   方法将实际转换置于函数体之后。对于   大函数,它分隔了函数的关键组件   从函数外部的其余部分定义的行为   接口

通过简单地浏览代码并查看方法/属性定义,使用较新的@语法可以更清楚地了解属性。

不幸的是,当他们第一次添加新的@property装饰器时,它只适用于装饰 getter 。如果您有 setter 删除器功能,则仍需使用旧语法。

幸运的是,在Python 2.6中,他们将gettersetterdeleter属性添加到属性中,因此您可以对所有属性使用新语法。

现在,没有理由使用旧语法来装饰函数和类。