Python - クラス - プロパティ
公開日:2019-03-04 更新日:2019-05-29
[Python]
1. 概要
プロパティ(クラスのデータ)の使い方です。
2.1 サンプル
クラスに speed と言うプロパティを定義して、クラスの利用者側から値の設定と取得を行っています。
class Car:
def __init__(self):
self.speed = 0
car = Car()
print( car.speed )
car.speed = 100
print( car.speed )
0
100
2.2 メソッドからプロパティを使う
同じクラスのメソッドからプロパティを参照する場合は、メソッドの第1引数の self を使います。
self は自動的に渡されるため、メソッドの呼び出し側での指定は不要です。
self を付けないと、メソッド内のローカル変数扱いとなり、メソッドから抜けると破棄されます。
self は自動的に渡されるため、メソッドの呼び出し側での指定は不要です。
self を付けないと、メソッド内のローカル変数扱いとなり、メソッドから抜けると破棄されます。
class Car:
def __init__(self):
self.speed = 0
def speed_up(self):
self.speed += 10
car = Car()
car.speed_up()
car.speed_up()
car.speed_up()
print( car.speed )
30
2.3 プロパティの動的追加
クラスの利用者側からプロパティの追加をしています。
インスタンスに関する追加情報を、元のクラスを変更せずに付与できます。
動的に外部から追加されるプロパティは、基本的にはクラス側では知りえないため、
クラス側からは使用しないプロパティになります。
インスタンスに関する追加情報を、元のクラスを変更せずに付与できます。
動的に外部から追加されるプロパティは、基本的にはクラス側では知りえないため、
クラス側からは使用しないプロパティになります。
class Car:
pass
car = Car()
car.note = "フェラーリ"
car2 = Car()
car2.note = "ポルシェ"
carList = [car, car2]
for c in [car, car2]:
print( c.note )
フェラーリ
ポルシェ
2.4 読み取り専用プロパティ
メソッドの前に @property を付けると、メソッドをプロパティのように、()を付けずに使用することができます。
クラス内の変数を直接公開した場合との違い
・読み取り専用にできる。
・プロパティの値が取得される際に、処理を実行することができる。
クラス内の変数を直接公開した場合との違い
・読み取り専用にできる。
・プロパティの値が取得される際に、処理を実行することができる。
class Car:
def __init__(self):
self._speed = 100
@property
def speed(self):
return self._speed
car = Car()
print(car.speed)
#エラー。設定はできない。
#car.speed = 150
100
2.5 書き込み可のプロパティ
メソッドの前に @プロパティ名.setter を付けると、書き込み可のプロパティになります。
読み取り専用プロパティと書き方が異なるため要注意。
プロパティに代入された値は、setter を付けたメソッドの2番目の引数で取得できます。
読み取り専用プロパティと書き方が異なるため要注意。
プロパティに代入された値は、setter を付けたメソッドの2番目の引数で取得できます。
class Car:
def __init__(self):
self._speed = 100
@property
def speed(self):
print("speed の取得")
return self._speed
@speed.setter
def speed(self, value):
print("speed の設定")
self._speed = value
car = Car()
print(car.speed)
car.speed = 200
print(car.speed)
speed の取得
100
speed の設定
speed の取得
200
2.6 property() を使ったプロパティの定義
property()を使うと、@property や @プロパティ名.setter を使わずにプロパティを定義できます。
定義方法は、getter、setter に該当するメソッドを、property() に渡して、プロパティの変数に設定するだけです。
getter、setter よりも下に定義する必要があるので要注意。
以下では setter も設定していますが、getter だけにすることもできます。
定義方法は、getter、setter に該当するメソッドを、property() に渡して、プロパティの変数に設定するだけです。
getter、setter よりも下に定義する必要があるので要注意。
以下では setter も設定していますが、getter だけにすることもできます。
class Car:
def __init__(self):
self._speed = 100
def get_speed(self):
print("speed の取得")
return self._speed
def set_speed(self, value):
print("speed の設定")
self._speed = value
speed = property(get_speed, set_speed)
car = Car()
print(car.speed)
car.speed = 200
print(car.speed)
speed の取得
100
speed の設定
speed の取得
200
2.7 privateプロパティ(プロパティの隠蔽)
Python にはアクセス修飾子(public, private)がありません。
外部から隠蔽したい場合には、変数名の先頭に __ を付けます。
但し、これでも完全ではなく、「_クラス名__プロパティ名」と言う名前で外部からアクセスできます。
dir() で名前の確認ができます(dir はディレクトリとは関係ありません)
また慣例で、変数名の先頭に _ を付けて、private である意志表示をします。
あくまでも意志表示のため、そのまま外部からアクセス可能です。
外部から隠蔽したい場合には、変数名の先頭に __ を付けます。
但し、これでも完全ではなく、「_クラス名__プロパティ名」と言う名前で外部からアクセスできます。
dir() で名前の確認ができます(dir はディレクトリとは関係ありません)
また慣例で、変数名の先頭に _ を付けて、private である意志表示をします。
あくまでも意志表示のため、そのまま外部からアクセス可能です。
class Car:
def __init__(self):
self.__speed = 100
car = Car()
#エラー。AttributeError
#print(car.__speed)
#オブジェクトのメンバリストの表示
print(dir(car))
#隠蔽されたプロパティの取得
print(car._Car__speed)
car._Car__speed = 200
['_Car__speed', '__class__', '__delattr__', '__dict__', '__dir__',
'__doc__', '__eq__', '__format__', '__ge__', '__getattribute__',
'__gt__', '__hash__', '__init__', '__init_subclass__', '__le__',
'__lt__', '__module__', '__ne__', '__new__', '__reduce__',
'__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__',
'__subclasshook__', '__weakref__']
100