2016-07-19 1 views
0

属性getterとsetterは "unpythonic"と考えられています。これを行うためのpythonicの方法は、通常の属性を使い、後で必要な場合はプロパティデコレータを使用することです属性がアクセスまたは設定されたときにある種の機能をトリガーする。"内部"リストの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) 

これは単にゲッター、セッター、ミューテータを簡単な属性を使用してではなく、作成の「神託」の考えに沿ったものであるように見えるでしょう私はaddDogメソッドを代わりに作成できました。厳密に言えば設定者ではありませんが(属性を設定するのではなく、属性の値を変更するため)、私の上記の解決策と比較して、設定者のように見えます。

しかし、その後、犬が追加されたときにいくつかの機能を起動する必要があるとします。犬を追加するのは、オブジェクトのプロパティを設定するのではなく、その属性の値であるリストを取得し、そのリストを変更するので、プロパティデコレータの使用に戻ることはできません。

このような状況に対処する "ピジョンソニック"な方法は何でしょうか?

+2

アイテムがリストに追加されたときの動作を変更する必要がある場合は、たとえば'cats'はバニラリストではなく、カスタム' list'サブクラスのインスタンスであり、それに対してビヘイビアを実装するか、カスタムラッパーでリストを返すために 'AnimalShelter .__ getattribute__'を使います。あるいは、避難所自体をリストのようにします(https://docs.python.org/3/library/collections.abc.html#collections.abc.MutableSequenceを参照)。 'woodgreen.append(Dog())'は、正しい内側のリストを選択し、必要なものを実行します。どんな追加の行動が必要ですか? – jonrsharpe

答えて

1

役に立たない gettersとsetters - Pythonは計算された属性を強力にサポートしています。これは、実装を適切にカプセル化してはいけないという意味ではありません。あなたの上記exempleで

、あなたのAnimalShelterクラスは、それが動物を「所有」だ処理する方法は、実装の詳細であると暴露されてはならないので、保護された属性を使用して、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 
+1

@samfrances 'self._dogs'のアンダースコアは、あなたの属性が保護されていることを伝える方法です(それは単なる意味論的なもので、何か特別なことをするためにPythonを組み込まない)[about understres](http://stackoverflow.com/questions/14671487 /前後にあるアンダースコア付きのPython属性とは何か? – pwnsauce

関連する問題