在Python面向对象中使用Getter/Accessor的好处是什么?
为什么在Python面向对象编程中使用getter和setter是好习惯?或者说,为什么不是?
我的课本上写着:
import random
class Die(object):
"""Simulate a generic die."""
def __init__(self):
self.sides = 6
self.roll()
def roll(self):
"""Updates the die with a random roll."""
self.value = 1+random.randrange(self.sides)
return self.value
def getValue(self):
"""Return the last value set by roll()."""
return self.value
def main():
d1,d2 = Die(),Die()
for n in range(12):
print d1.roll(),d2.roll()
main()
getValue()方法被称为getter或访问器,它返回值实例变量的值。为什么要写这样的函数?为什么不直接使用实例变量呢?我们将在本章末尾的常见问题解答中讨论这个问题。
然而,章节末尾并没有常见问题解答,所以并没有解释为什么在Python的面向对象编程中使用getter。
我试着在其他地方查找,但没有找到好的解释。大多数在Stack Overflow上的回答都是关于Java的,而且我听说这和Python没有关系...
有没有人能帮我理解一下,为什么使用getter和setter是好习惯?或者如果不是,为什么呢?
2 个回答
4
在Java中,你应该使用getter和setter:
这是一个被认为很好的做法,因为它可以把对象内部的状态封装起来。这样,你就可以在不改变对象外部接口的情况下,修改对象内部的实现和数值的含义,进行一些复杂的操作。
在Python中,你可以使用getter和setter:
不过在访问属性值时,Python并没有特别强调这一点,因为Python提供了一种Java没有的功能:属性!
class A(object):
def __init__(self):
self._x = 1
@property
def x(self):
return self._x +2
@x.setter
def x(self, value):
self._x = value
这就是你可以用来在不改变属性接口的情况下,改变属性含义的内置语法。使用它就像使用普通的属性语法一样简单。
8
因为在Python中有属性的概念:
class Foo:
def __init__(self, value):
self.__value = value
@property
def value(self):
return self.__value
@value.setter
def set_value(self, that):
if that < 0:
self.__value = 0
else:
self.__value = that
属性让你感觉是在处理一个普通的变量,但实际上你是在使用设置器和获取器。这使得我们可以更好地利用Python的一个重要特性:鸭子类型。
所以,我可以这样做:
class Bar:
def __init__(self, value, other):
self.value = value
self.other = other
def __str__(self):
return ''.join(['Oh joy', str(self.value), str(self.other), '!'])
然后在这个函数里:
def stuff(x):
return x.value + 1
我可以传入一个Bar
类型的对象或者一个Foo
类型的对象,这并没有关系。鸭子类型让它“自然而然地工作”。