Pythonic访问器/变异器;“内部”;列表
我知道属性getter和setter被认为是“非Python的”,pythonic的方法是简单地使用普通属性,如果以后需要在访问或设置属性时触发某些功能,则使用属性decorator e、 g 但是,例如,当属性的值是列表时,这将如何应用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
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())
将选择正确的内部列表并执行您需要的其他操作。您还需要什么其他行为?@samfrancesself.\u dogs
中的下划线是一种表示您的属性受保护的方式(它只是语义,并不指示python执行任何特殊操作)