Python クラス #4
株式会社リュディアです。今回も引き続きクラスについてまとめていきます。
前回までの Python クラスについてのまとめへのリンクは以下を参考にしてください。
今回はクラス変数とインスタンス変数のカプセル化についてまとめます。クラス変数とインスタンス変数のまとめとしては最後になります。以下の例から見ていきます。
class VegetableClass():
num_of_types = 800
def __init__(self, c):
self.color = c
lettuce = VegetableClass('green')
tomato = VegetableClass('red')
print(VegetableClass.num_of_types)
# 800
前のまとめで使ったのと同じクラス変数 num_of_types を出力するだけのコードです。では次の例を見てください。
class VegetableClass():
__num_of_types = 800
def __init__(self, c):
self.color = c
lettuce = VegetableClass('green')
tomato = VegetableClass('red')
print(VegetableClass.__num_of_types)
# ---------------------------------------------------------------------------
# AttributeError Traceback (most recent call last)
# <ipython-input-34-0bddfc2fbb3a> in <module>
# 7 tomato = VegetableClass('red')
# 8
# ----> 9 print(VegetableClass.__num_of_types)
#
# AttributeError: type object 'VegetableClass' has no attribute '__num_of_types'
最初の例と何が違うかわかりますか?クラス変数 num_of_types を __num_of_types に変更しました。変数名の前にアンダースコアを 2 つつけました。すると print 文でアクセスできなくなりました。これは偶然ではなくて名前付けでクラス内の変数のカプセル化を制御する Python の機能です。
C++ や Java ではクラスの変数や関数に対して public, private, protected といったカプセル化のためのキーワードが定義されていますが Python ではこのような機能は提供されていません。つまりすべて public 、公開されているということになります。そこで変数名の前にアンダースコアを1つまたは2つつけることでカプセル化を実現できるように言語仕様ではなく言語処理系が頑張っているわけです。
クラス変数と同じようにインスタンス変数についても試してみましょう。以下の例を見てください。
class VegetableClass():
num_of_types = 800
def __init__(self, c):
self.__color = c
lettuce = VegetableClass('green')
tomato = VegetableClass('red')
print(VegetableClass.num_of_types)
print(lettuce.__color)
# 800
# ---------------------------------------------------------------------------
# AttributeError Traceback (most recent call last)
# <ipython-input-35-c11764c1bdc6> in <module>
# 8
# 9 print(VegetableClass.num_of_types)
# ---> 10 print(lettuce.__color)
#
# AttributeError: 'VegetableClass' object has no attribute '__color'
今度はインスタンス変数 color を __color に変更してみました。前の例と同様に print 文でアクセスできない旨のエラーが出ていますね。
このようにクラス変数、インスタンス変数をクラス外に見せたくない場合は __ をつけることでいわゆるカプセル化を実現できます。PEP8 の中にも公開されていないメソッドやインスタンス変数にだけ、アンダースコアを先頭に付けてください。とありますので是非利用してください。PEP8へのリンクは以下を参照ください。
Python のクラスに関するまとめの続きは以下からどうぞ。
では、ごきげんよう。