我现在正在努力学习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会选择什么?
答案 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中,他们将getter
,setter
和deleter
属性添加到属性中,因此您可以对所有属性使用新语法。
现在,没有理由使用旧语法来装饰函数和类。