为什么在PythonOOP中使用getter/accessor是一种好的实践(或者说它不是)?

为什么在PythonOOP中使用getter/accessor是一种好的实践(或者说它不是)?,python,oop,python-2.7,getter,getter-setter,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

为什么—或者为什么不—在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()
 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), '!'])
getValue()方法称为getter或accessor,返回value实例变量的值。 为什么要写这种函数?为什么不直接使用实例变量呢?我们将在本章末尾的常见问题解答中对此进行讨论

但是,本章末尾没有常见问题解答,因此没有解释为什么在Python OOP中使用getter

我试过在其他地方阅读,但在任何地方都找不到好的解释。关于SO的大多数答案都是关于Java的,我读到它与Python无关


有人能帮我理解为什么使用它们是一种好的做法吗?如果没有,为什么不呢?

因为在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
然后在函数中:

 def stuff(x):
   return x.value + 1
我可以通过一种类型的
Bar
或一种类型的
Foo
,这并不重要。Duck类型可以让它“正常工作”。

在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

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

实际上,这不是一个好的做法。它是用Java编写的,但不是用Python编写的。我想作者对Python不是很熟悉。事实正好相反,请不要关门。接近投票引用的问题通常是OOP。有几个答案提到了Python,但我认为这个问题有一个特定于Python的版本是有效的。我认为这里真正的问题是,为什么你要建模一个
Die
,为什么你觉得在任何情况下都有必要记住它的
@user2071506,我建议你联系教科书的作者,提到你找不到你提到的参考资料。在Java中需要它们的真正原因是,当你需要添加一些额外的行为时,重构所有使用属性访问的东西是一件痛苦的事。那个“封装”的胡言乱语只是为了掩盖一个糟糕的语言设计决策。@gnibbler完全正确!但我不会这么说,因为我知道他们在外面,java爱好者,他们是军团,他们在寻找鲜血。但我不会对我的血液使用访问器!啊哈-关于duck类型,我认为这是完全无关的。另外,您可能希望将“处理变量”更改为“处理属性”。@StevenRumbalski实际上我认为Duck类型与Python的核心非常相关。但是我同意,“属性”是一个更好的术语。当然,Python是关于duck类型的,但属性不是这样的。他们将函数调用伪装成属性访问。很好的一点是,它们看起来和属性访问完全一样,所以你可以从没有属性开始,然后在保证的情况下添加它们。嗯,我真的不明白@属性似乎与“get_value”相同。@user2071506但看起来不像是在创建访问器。它看起来像一个成员变量。您使用它并将其视为一个(在大多数情况下)