Pythonic访问器/修改器用于“内部”列表

11 浏览
0 Comments

Pythonic访问器/修改器用于“内部”列表

我知道属性的getter和setter被认为是“非Pythonic”的,而在Python中处理事务的方式是简单地使用普通属性,如果以后需要在访问或设置属性时触发某些功能,则使用property修饰符。\n例如:What\'s the pythonic way to use getters and setters?\n但是,当属性的值是一个列表时,这如何应用呢?\n例如:\n

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

\n假设最初,接口的工作方式如下:\n

# 创建一个新的动物收容所
woodgreen = AnimalShelter()
# 向收容所添加一些动物
dog1 = Dog()
woodgreen.dogs.append(dog1)

\n这似乎符合“Pythonic”的思想,只是使用直接的属性而不是创建getter、setter、变异器等。我也可以创建一个addDog方法。但是,虽然严格来说不是一个setter(因为它改变了属性的值而不是设置属性),但与上述解决方案相比,它仍然类似于setter。\n但是,假设以后需要在添加狗时触发一些功能。你无法回到使用property修饰符,因为添加狗不是在对象上设置属性,而是检索作为该属性值的列表,并改变该列表。\n在这种情况下,什么是处理这种情况的“Pythonic”方式?

0
0 Comments

Pythonic访问器/修改器用于“内部”列表的问题出现的原因是,使用无用的getter和setter方法是不符合Python风格的,因为Python对计算属性有很好的支持。但这并不意味着你不应该正确封装你的实现。

在上面的例子中,AnimalShelter类处理其“拥有的”动物的方式是一个实现细节,不应该被暴露出来,所以使用受保护的属性并公开一组相关的公共方法/属性是完全符合Python风格的:

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

在`self._dogs`中的下划线是一种告诉属性受保护的方式(这只是语义上的,它不会给Python带来任何特殊的指令)。

解决方法是使用受保护的属性和相关的公共方法/属性来封装内部列表,并使用浅拷贝来返回列表,以避免直接操作内部列表。

这种方法可以确保类的内部实现细节不被外部访问,并且通过公共方法/属性的方式来操作内部列表,保持了代码的可读性和易用性。这是一种典型的Pythonic风格,符合Python的设计原则。

0