在Python面向对象中使用Getter/Accessor的好处是什么?

9 投票
2 回答
2377 浏览
提问于 2025-04-18 00:20

为什么在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类型的对象,这并没有关系。鸭子类型让它“自然而然地工作”。

撰写回答