Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Pythonic访问器/变异器;“内部”;列表_Python_Oop_Design Patterns_Getter Setter - Fatal编程技术网

Pythonic访问器/变异器;“内部”;列表

Pythonic访问器/变异器;“内部”;列表,python,oop,design-patterns,getter-setter,Python,Oop,Design Patterns,Getter Setter,我知道属性getter和setter被认为是“非Python的”,pythonic的方法是简单地使用普通属性,如果以后需要在访问或设置属性时触发某些功能,则使用属性decorator e、 g 但是,例如,当属性的值是列表时,这将如何应用 class AnimalShelter(object): def __init__(self): dogs = [] cats = [] class Cat(object): pass class Dog(o

我知道属性getter和setter被认为是“非Python的”,pythonic的方法是简单地使用普通属性,如果以后需要在访问或设置属性时触发某些功能,则使用属性decorator

e、 g

但是,例如,当属性的值是列表时,这将如何应用

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、setter、mutator等。我本可以创建一个
addDog
方法。但是,虽然严格来说不是setter(因为它改变了属性的值而不是设置属性),但与我上面的解决方案相比,它看起来仍然像setter

但是,假设以后你需要在添加狗的时候触发一些功能。您不能依赖于使用属性装饰器,因为添加狗并不是在对象上设置属性,而是检索作为该属性值的列表,并改变该列表

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

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

在上面的示例中,您的
AnimalShelter
类处理其“拥有的”动物的方式是一个实现细节,不应该公开,因此使用protected属性并公开一组相关的公共方法/属性完全是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

如果在将项目添加到列表时需要修改行为,则可以将例如
cats
作为自定义
list
子类的实例,而不是普通列表,并在其上实现行为,或者使用
AnimalShelter.\uuuu getattribute\uuuu
使用自定义包装返回列表。或者,将避难所本身列为列表(请参见),例如,
woodgreen.append(Dog())
将选择正确的内部列表并执行您需要的其他操作。您还需要什么其他行为?@samfrances
self.\u dogs
中的下划线是一种表示您的属性受保护的方式(它只是语义,并不指示python执行任何特殊操作)