为什么在Python OOP中使用Getters / Accessors是好的(或者不是)好的做法?

时间:2014-03-28 14:33:08

标签: python oop python-2.7 getter getter-setter

为什么 - 或者为什么不 - 在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无关 ......

有人可以帮助我理解为什么使用它们是好的做法?或者如果没有,为什么不呢?

2 个答案:

答案 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)

在Java中,您应该使用getter和setter:

它被认为是一种很好的做法,因为它封装了对象的内部状态,因此您可以更改对象的内部并更改值的含义,使用它执行复杂的操作而不更改其接口。

在python中你可以使用getter和setter:

但是对于访问属性的值并没有那么强调,因为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

这是您在不更改其界面的情况下更改属性含义的内置语法。使用它就像使用平均属性语法一样。