我正在阅读“绝对初学者的Python编程”,并且在那里有这段代码:
@property
def mood(self):
unhappiness = self.hunger + self.boredom
if unhappiness < 5:
m = "happy"
elif 5 <= unhappiness <= 10:
m = "okay"
elif 11 <= unhappiness <= 15:
m = "frustrated"
else:
m = "mad"
return m
所有这一切都是即时计算并返回计算结果。它不提供对私有属性或类的任何属性的访问。这是财产而不是方法更好吗?
答案 0 :(得分:16)
属性不用于提供对私有属性的访问。属性旨在为您提供使零参数方法可访问的选项,就好像它们是属性一样,以便给定的“属性”可以实现为计算或实际属性,而无需更改类的接口。
因此,它通常不是一个“更好”的问题,而是一个依赖于背景的利弊设计决策。
在这种情况下,无论此对象支持x.hunger
,x.boredom
和x.mood
。为什么不x.mood()
?您可以,虽然在界面中永久地公开它 计算并且不存储。
如果该类的先前版本具有“真实”mood
属性,并且该对象的必需不变量意味着更新boredom
或hunger
的任何内部方法也必须谨慎将mood
设置为一致,然后引入该属性将是一个很好的重构;界面保持不变,但现在保证永久保持不变,而不是必须小心维护。整个领域的错误都无法发生。
另一方面,如果mood
计算成本很高,或者有副作用,那么作为常规方法可能会好得多。使其看起来像属性访问意味着客户端代码程序员可能认为它作为属性访问,这是廉价和非破坏性的;这将是错误或性能问题的丰富来源。
答案 1 :(得分:3)
我认为没有任何真正的区别。
它只允许您obj.mood
代替obj.mood()
答案 2 :(得分:1)
这只是一个品味问题。
在访问相当便宜的情况下使用属性,例如只查询“私有”属性或简单计算。
在一个相当“复杂”的过程发生的地方使用一个方法,这个过程是主要的。
人们习惯使用getter和setter方法,但越来越倾向于使用属性。
以Serial
pyserial
类getBaudRate()
为例。作为遗产,它有setBaudRate()
和baudrate
等方法,但建议使用{{1}}作为查询和写入属性来查询和设置波特率。
答案 3 :(得分:1)
这基本上是一种偏好。它允许您输入object.property
而不是object.property()
。
那你什么时候应该使用哪个?你必须使用上下文来决定。如果你拥有的方法根据对象的属性返回一个值,它可以节省你创建变量的时间,并将它设置为等于某个生成器方法(例如:property = object.generateProperty()
。它是否更有意义跳过此步骤,并使generateProperty()
成为自己的属性?
这是我理解的一般概念。