入門Python3という書籍でPythonを学習中の初心者です。  
現在、プロパティについて学んでいるのですが  
組み込み関数のproperty()の挙動がよく分かりません。

次のソースコードでpropertyがどのように動いているかを  
詳しく教えていただけると有難いです。

```

    class Duck():
        def __init__(self, input_name):
            self.hidden_name = input_name
        def get_name(self):
            print('inside the getter')
            return print(self.hidden_name)
        def set_name(self, input_name):
            print('inside the setter')
            self.hidden_name = input_name
        name = property(get_name, set_name)
    
    fowl = Duck('Howard')
    fowl.name
    
    fowl.name = 'Daffy'
    fowl.name
    
```

なお、ソースコードは同書から引用しています。  
nameに何も代入されていなければ第一引数の関数が、  
何かが代入されていたら第二引数の関数が実行されると  
考えましたが、腑に落ちません。

簡単な例としてpropertyを用いた、他のソースコードを  
元に説明して頂けると幸いです。
CC BY-SA 3.0
2016-12-30T15:13:49.997
31546
2016-12-31T06:25:00.497
2016-12-31T06:25:00.497
3605
20061
question
python
Python プロパティについて
fowl.name に何も代入されていなければ get_name 関数が、  
何か代入されれば set_name 関数の引数 input_name に  
その値を指定したことになります

fowl.name は  
fowl.get_name() とするのと同じで  
print('inside the getter')  
print(fowl.hidden_name) とするのと同じです

fowl.name = 'Daffy' は  
fowl.set_name('Daffy') とするのと同じで  
print('inside the setter')  
fowl.hidden_name = 'Daffy' とするのと同じです

self.hidden_name は hidden と名付けてあるので外からアクセスしないという前提なんでしょう。  
ですが fowl.hidden_name で外からアクセスできてしまうので、  
この例で getter,setter を設定する意義は print('inside the getter') することくらいしかありません。  
self.hidden_name は self.__hidden_name として private にしたほうがわかりやすいですし  
外からアクセスしないものは private化して name のみでアクセスするようにしたほうがわかりやすいです

return print(self.hidden_name) は getter なので  
値を返すべきで return self.hidden_name とするほうが良いと思います

getter,setter は外部から「どのようなアクセスを許可するか」と  
print('inside the ..') のように「関数内で別の処理を加える」ことができます

```

    class Duck():
        def __init__(self, input_name):
            self.__hidden_name = input_name
    
        def __get_name(self):
            return self.__hidden_name
    
        def __set_name(self, input_name):
            self.__hidden_name = 'hello:' + input_name
    
        name = property(__get_name, __set_name)
    
    
    fowl = Duck('Howard')
    print(fowl.name)
    fowl.name = 'Daffy'
    print(fowl.name)
    
    # 以下はエラーになります
    fowl.__get_name()
    fowl.__set_name('Daffy')
    print(fowl.__hidden_name)
    fowl.__hidden_name = 'Daffy'
    
```

name 以外をプライベート化することで  
def __get_name(): ... と property の __get_name を削除すれば  
外から __set_name で値を設定することはできても取得はできなくなります  
同様に __set_name を削除すれば値の取得はできても設定はできなくなります

name = property() は @property で同じことができるので詳しくは 「デコレータ getter setter」
とかでぐぐってみてください  
ちなみに private化 しても fowl._Duck__hidden_name でアクセスできたりします。 unittestとかで使うかもしれません
CC BY-SA 3.0
2016-12-30T23:21:06.253
31549
2016-12-30T23:21:06.253
20062
31546
answer