"internal" 列表的 Pythonic 访问器/修改器

Pythonic accessors / mutators for "internal" lists

我知道属性 getter 和 setters 被认为是 "unpythonic",pythonic 的方法是简单地使用普通属性并使用 属性 装饰器如果您稍后需要在访问或设置属性时触发某些功能。

例如What's the pythonic way to use getters and setters?

但是,当属性的值是一个列表时,这如何应用?

class AnimalShelter(object):
    def __init__(self):
        dogs = []
        cats = []

class Cat(object):
    pass

class Dog(object):
    pass

说一开始,界面是这样的:

# Create a new animal shelter
woodgreen = AnimalShelter()

# Add some animals to the shelter
dog1 = Dog()
woodgreen.dogs.append(dog1)

这似乎符合 "pythonic" 的想法,即只使用简单的属性而不是创建 getter、setters、mutator 等。我本可以创建一个 addDog方法代替。但是,虽然严格来说不是 setter(因为它改变了属性的值而不是设置属性),但与我上面的解决方案相比,它仍然看起来像 setter。

但是,说以后你需要在添加狗时触发一些功能。你不能退回到使用 属性 装饰器,因为添加狗并不是在对象上设置 属性,而是检索一个列表,该列表是该属性的值,并改变该列表.

处理这种情况的 "pythonic" 方法是什么?

非Pythonic 的是无用的 getter 和setter - 因为Python 对计算属性有强大的支持。这并不意味着您不应该正确封装您的实现。

在你上面的例子中,你的 AnimalShelter class 处理它的方式 "owned" 动物是一个实现细节,不应该公开,所以使用受保护的属性完全是 pythonic 和公开一组相关的 public 方法/属性:

class AnimalShelter(object):
    def __init__(self):
        self._dogs = []
        self._cats = []

    def add_dog(self, dog):
        if dog not in self._dogs:     
            self._dogs.append(dog)

    def get_dogs(self):
        return self._dogs[:] # return a shallow copy

    # etc