Python、はじめました

非IT系私文卒リーマン vs Python の全記録

Python SoloLearn Object-Oriented Programming③

f:id:pokita:20180421094155p:plain 

PropertyについてはSoloLearnだけでは全然わけわかめ
ネットで調べてもなかなか的を射た理解ができず、
書籍の初めてのPythonに頼りました。
最後の節のA Simple Gameについても難所過ぎたのでここで整理します。

 

 

Property

 propertyとは

Properties provide a way of customizing access to instance attributes. 

propertyとはインスタンスの属性へのアクセスをカスタマイズする方法である。

 

?????????

 

以下propertyの作り方とその実用法が続く。
propertyについての認識が中途半端だと以後引っかかることが多いので、
ここで少しpropertyの解説。


公式ドキュメントはこちら

 

ちなみに実用例はこちらのサイトがよかったです。

 

プロパティ - Python学習講座

 

そもそもpropertyとはビルドインオブジェクトである。

help(property)
>>><class 'type'>
Help on class property in module builtins:
class property(object)
| property(fget=None, fset=None, fdel=None, doc=None)
|
|Typical use is to define a managed attribute x
|
| class C(object):
| def getx(self): return self._x
| def setx(self, value): self._x = value
| def delx(self): del self._x
| x = property(getx, setx, delx, "I'm the 'x' property.")

@property(プロパティデコレーション)

直下に定義した関数をpropertyクラスの引数に代入しているのだ。
(デコレーションについてはここが詳しかったです。)

 つまり、これは

class Person:
def __init__(self, name):
self._name = name

@property
def name(self):
return self._name

              ↓

class Person:
def __init__(self, name):
self._name = name

def name(self):
return self._name

name = property(name)

 

ということ。

propertyを学ぶ上ではこのブログがとても参考になりました♨

qiita.com


以下、propertyの理解で躓いたとこ2点。
①propertyは"class property"というところ.。
②propertyとは"to define a managed attribute x"というところ。
 

①propertyはクラスオブジェクト(≠関数オブジェクト)

いろんなサイトを見てみると、

”property関数は~~~~~~"

という表現を多く見るが、プロパティは関数オブジェクトではない。
intやstr同様ビルドインオブジェクトなのだ。
property(fget=~, fset=~, fdel=~, doc=~)
となるため紛らわしいのだが、この引数はpropertyクラスに渡される引数であり、
戻り値を出すために関数に渡される引数とは全くの別物である。 

とまで書いて改めて公式のドキュメントを見直したところ、こんな記載が。

2. 組み込み関数(原文)

Python インタプリタには数多くの関数と型が組み込まれており、いつでも利用できます。それらをここにアルファベット順に挙げます。

    組み込み関数    
abs() dict() help() min() setattr()
all() dir() hex() next() slice()
any() divmod() id() object() sorted()
ascii() enumerate() input() oct() staticmethod()
bin() eval() int() open() str()
bool() exec() isinstance() ord() sum()
bytearray() filter() issubclass() pow() super()
bytes() float() iter() print() tuple()
callable() format() len() property() type()
chr() frozenset() list() range() vars()
classmethod() getattr() locals() repr() zip()
compile() globals() map() reversed() __import__()
complex() hasattr() max() round()  
delattr() hash() memoryview() set()  

 

………………………

 

ビルドイン関数とビルドインオブジェクトをそれぞれ同じ章(組み込み関数)
にまとめていることからも、Pythonは厳密に両者を分けてるということではなさそう。
property関数を使うことで、引数に基づいたpropertyオブジェクトが作成される。
ぐらいの認識でOKかな。

 

②propertyは代入された"属性"の操作を定義するオブジェクト

クラス定義内において、@property以下に定義された属性には、
実際には上で見たような代入が行われている。
分かりやすくC風のインデントで書くと以下の感じ。


クラス定義内において{
    {属性の
       {呼び出されたとき・代入されたときの振る舞いを定義している}}}
のである。

 

これより、以下のようなコードを書くことができる。

class Pro:
def __init__(self):
self.a = 5

def pro_get(self):
print("get={0}".format(self.a))

def pro_set(self, value):
print("set={0}".format(value))

x = property(pro_get, pro_set)


p = Pro()
p.x
>>>get=5
p.x = 1
>>set = 1

Proクラスのインスタンスの属性x(property)にが呼び出されると、
x(property型)の第一引数pro_getが呼び出される。
Proクラスのインスタンスの属性x(property)に代入されると、
x(property型)の第二引数pro_setが呼び出される。
この際、代入された値(=の右辺)はvalueとしてpro_getの引数に渡される。

 

今回はここまで。