3 回答
TA贡献2065条经验 获得超14个赞
在像Java这样的依赖getter和setter的语言中,除了他们说的话,他们不应该做任何事情,也不希望他们做任何事情-如果x.getB()除了返回逻辑属性的当前值之外,什么都不做b,或者是否x.setB(2)做了任何事情,都将是令人惊讶的需要少量的内部工作才能获得x.getB()回报2。
但是,对于这种预期行为没有语言保证,即,以名称开头get或为方法的方法主体受到编译器强制的约束,set而是由常识,社会习俗,“样式指南”和测试决定。
具有属性(包含但不限于Python的语言集)的语言中的x.b访问行为和赋值行为与Java中的getter和setter方法完全相同:期望相同,同样缺乏语言强制保证。x.b = 2
属性的首个胜利是语法和可读性。不得不写,例如
x.setB(x.getB() + 1)
而不是显而易见的
x.b += 1
要求向众神报仇。在支持属性的语言中,绝对没有充分的理由迫使该类的用户经历这种拜占庭样板的旋转,从而不影响其代码的可读性。
具体来说,在Python中,使用属性(或其他描述符)代替getter和setter还有一个更大的好处:如果并且当您重新组织类时,不再需要底层的setter和getter,则可以(无需破坏类的已发布的API)简单地消除了这些方法和依赖于它们的属性,从而使的类b成为普通的“存储”属性,x而不是通过计算获得并设置了“逻辑” 属性。
在Python中,直接(在可行的情况下)而不是通过方法进行操作是一项重要的优化,系统地使用属性使您能够在可行的情况下执行此优化(始终直接公开“正常存储的属性”,只有那些确实需要在访问时进行计算的属性)和/或通过方法和属性进行设置)。
因此,如果您使用getter和setter代替属性,那么除了会影响用户代码的可读性之外,您还无偿地浪费了机器周期(以及浪费在这些周期中计算机的能量;-),这也是没有充分理由的任何。
您对属性的唯一争论是,例如“通常,外部用户不会因分配而产生任何副作用”;但是您错过了这样一个事实,即同一用户(使用Java等getter和setter普遍存在的语言)不会期望(可观察到的)“副作用”由于调用setter而产生(或者对getter的影响更少) ;-)。它们是合理的期望,作为班级作者,您有责任尝试并适应它们-无论是直接使用setter和getter还是通过属性使用,都无济于事。如果您的方法具有明显的可观察到的副作用,请不要将其命名为getThis,setThat也不要通过属性使用它们。
该属性“隐藏实现”的抱怨是没有道理的全资:大部分都面向对象是有关实现信息隐藏-制造类负责提出一个逻辑接口与外部世界和内部实现它,因为它最能。就像属性一样,getter和setter是实现此目标的工具。属性只是做得更好(使用支持它们的语言;-)。
TA贡献1853条经验 获得超6个赞
这样做的目的是让您避免在实际需要时才编写getter和setter。
因此,首先要编写:
class MyClass(object):
def __init__(self):
self.myval = 4
显然,您现在可以写了myobj.myval = 5。
但是后来,您决定确实需要二传手,因为您想同时做一些聪明的事情。但是您不需要更改所有使用您的类的代码-因此您可以将setter包装在@property装饰器中,并且一切都可以正常进行。
添加回答
举报