为什么 - 或者为什么不 - 在Python OOP中专门使用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或accessor)返回值实例变量的值。 为什么要写这种功能?为什么不简单地使用实例变量?我们将在本章末尾的常见问题解答中解决这个问题。
但是,本章末尾没有常见问题解答,因此从未解释为什么在Python OOP中使用getter。
我尝试过阅读其他地方,但我在任何地方都找不到好的解释。关于SO的大多数答案都是关于Java的,我读过它与Python无关 ......
有人可以帮助我理解为什么使用它们是好的做法?或者如果没有,为什么不呢?
答案 0 :(得分: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
属性使您看起来正在处理属性,但事实上,您正在处理setter和getter。这样可以更好地使用Python的一个定义特征:Duck Typing。
因此,我可以做到以下几点:
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
类型,但这无关紧要。鸭子打字会让它“正常工作。”
答案 1 :(得分:3)
它被认为是一种很好的做法,因为它封装了对象的内部状态,因此您可以更改对象的内部并更改值的含义,使用它执行复杂的操作而不更改其接口。
但是对于访问属性的值并没有那么强调,因为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
这是您在不更改其界面的情况下更改属性含义的内置语法。使用它就像使用平均属性语法一样。