为什么(或不是)在Python OOP中使用Getters/Accessors是一种好习惯?

BBe*_*dit 8 python oop getter getter-setter python-2.7

为什么 - 或者为什么不 - 在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()
Run Code Online (Sandbox Code Playgroud)

getValue()方法(称为getter或accessor)返回值实例变量的值.为什么要写这种功能?为什么不简单地使用实例变量?我们将在本章末尾的常见问题解答中解决这个问题.

但是,本章末尾没有FAQ,因此从未解释为什么在Python OOP中使用getter.

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

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

whe*_*ies 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
Run Code Online (Sandbox Code Playgroud)

属性使您看起来正在处理属性,但事实上,您正在处理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), '!'])
Run Code Online (Sandbox Code Playgroud)

然后在功能中:

 def stuff(x):
   return x.value + 1
Run Code Online (Sandbox Code Playgroud)

我可以传递一种类型Bar或一种类型,Foo这无关紧要.鸭子打字会让它"正常工作".

  • @StevenRumbalski实际上我认为Duck Typing是高度相关的,并且是Python核心的核心.但我同意,"属性"是一个更好的术语. (2认同)