Pythonにおけるクラスの使い方とスコープを確認してみる
会社の若い子たちがPhysonで機械学習とかやっているようなので自分も勉強してみることにしました。
基本的な文法はなんとなくわかる気がするので、Pythonにおけるクラスの使い方とスコープから初めてみたいと思います。
自分のお勉強目的の備忘録なのでわかりにくい表現を使うかもしれませんがお許し下さいm(T▽T)m
スコープ確認用のクラス
今回は動作確認用に以下のクラスを準備しました。
# coding: utf-8 class testClass : # publicなクラス変数 class_variable_A = 1 # privateなクラス変数 __class_variable_B = 2 # コンストラクタ def __init__(self) : print( "コンストラクタを呼び出し" ) # publicなインスタンス変数 self.instance_variable_A = 3 # privateなインスタンス変数 self.__instance_variable_B = 4 # デストラクタ def __del__(self) : print( "デストラクタを呼び出し" ) # publicなクラスメソッド @classmethod def class_method_A(cls) : print( "publicなクラスメソッドを呼び出し" ) # privateなクラスメソッド @classmethod def __class_method_B(cls) : print( "privateなクラスメソッドを呼び出し" ) # publicなインタンスメソッド def instance_method_A(self) : print( "publicなインタンスメソッド" ) # privateなインタンスメソッド def __instance_method_B(self) : print( "privateなインタンスメソッド" )
コンストラクタ
インスタンスが作成されるタイミングで呼び出されるメソッドです。
書き方は以下のとおり。「__init__」という関数を定義する感じです。
引数のselfは、インスタンス自身を示す特殊な引数。JavaやC#でいうthis句みたいなもの。
なお、ここではselfという変数名にしていますが別にselfとする必要はありません。
ただ伝統的にselfが使われるようなので従っておきます。
def __init__(self) :
なおクラスからインスタンスを作成するには以下のような感じです。
JavaやC#のようにnew句は必要ないようです。
またself変数も指定する必要はありません。
※以降の説明ではobjという変数はtestClassクラスのインスタンスを指します。
obj = testClass()
デストラクタ
インスタンスが破棄されるタイミングで呼び出されるメソッドです。
書き方は以下のとおり。「__del__」という関数を定義する感じです。
selfはコンストラクタと同じです。
def __del__(self) :
publicなクラス変数
javaやC#でいうpublic staticなフィールド変数みたいなもののようです。
宣言はclass内で普通に変数宣言すればよいようです。
「クラス名.変数名」でアクセス可能です。
print("class_variable_A =", testClass.class_variable_A)
また、インスタンス名.変数名でもアクセス可能です。
print("class_variable_A =", obj.class_variable_A)
privateなクラス変数
javaやC#でいうprivate staticなフィールド変数みたいなもののようです。
宣言はpublicなクラス変数と同様ですが、変数名の前に__を付ける必要があります。
privateとしていますが「クラス名._クラス名__変数名」でアクセスができてしまいます。
print("__class_variable_B =", testClass._testClass__class_variable_B)
また、「インスタンス名._クラス名__変数名」でもアクセス可能です。
print("__class_variable_B =", obj._testClass__class_variable_B)
publicなインスタンス変数
javaやC#でいうpublic なフィールド変数のようです。
コンストラクタやインスタンスメソッドの引数であるselfを使って、「self.変数名」で宣言可能です。
「インスタンス名.変数名」でアクセス可能です。
print("instance_variable_A =", obj.instance_variable_A)
privateなインスタンス変数
javaやC#でいうprivateなフィールド変数のようです。
コンストラクタやインスタンスメソッドの引数であるselfを使って、「self.__変数名」で宣言可能です。
privateとしていますが「インスタンス名._クラス名__変数名」でアクセスができてしまいます。
print("__instance_variable_B =", obj._testClass__instance_variable_B)
publicなクラスメソッド
javaやC#でいうpublic staticなメソッドみたいなものです。
宣言はクラス内で関数宣言した後に@classmethodというアノテーションを付けます。
引数clsはクラス自身を示す特殊な引数です。
@classmethod def class_method_A(cls) :
「クラス名.メソッド名」でアクセス可能です。
testClass.class_method_A()
また、インスタンス名.メソッド名でもアクセス可能です。
obj.class_method_A()
privateなクラスメソッド
javaやC#でいうprivate staticなメソッドみたいなもののようです。
宣言はpublicなクラス変数と同様ですが、メソッド名の前に__を付ける必要があります。
privateとしていますが「クラス名._クラス名__メソッド名」でアクセスができてしまいます。
testClass._testClass__class_method_B()
また、「インスタンス名._クラス名__メソッド名」でもアクセス可能です。
obj._testClass__class_method_B()
publicなインスタンスメソッド
javaやC#でいうpublicなメソッドのようです。
宣言はクラス内で関数宣言します。引数にはコンストラクタ同様にselfを持ちます。
「インスタンス名.変数名」でアクセス可能です。
obj.instance_method_A()
privateなインスタンスメソッド
javaやC#でいうprivateなメソッドみたいなもののようです。
宣言はpublicなインスタンスメソッドと同様ですが、メソッド名の前に__を付ける必要があります。
privateとしていますが「インスタンス名._クラス名__メソッド名」でアクセスができてしまいます。
obj._testClass__instance_method_B()
動作確認
動作確認用に以下のプログラムを用意しました。
# coding: utf-8 from test import testClass # インスタンス化 obj = testClass() # publicなクラス変数にアクセス print("class_variable_A =", testClass.class_variable_A) # クラスからアクセス print("class_variable_A =", obj.class_variable_A) # インスタンスからアクセス # privateなクラス変数にアクセス #print("__class_variable_B =", testClass.__class_variable_B) # クラスからアクセス:エラー print("__class_variable_B =", testClass._testClass__class_variable_B) # クラスからアクセス #print("__class_variable_B =", obj.__class_variable_B) # インスタンスからアクセス:エラー print("__class_variable_B =", obj._testClass__class_variable_B) # インスタンスからアクセス # publicなインスタンス変数にアクセス print("instance_variable_A =", obj.instance_variable_A) # インスタンスからアクセス # privateなインスタンス変数にアクセス #print("__instance_variable_B =", obj.__instance_variable_B) # インスタンスからアクセス:エラー print("__instance_variable_B =", obj._testClass__instance_variable_B) # インスタンスからアクセス # publicなクラスメソッドを呼び出し testClass.class_method_A() # クラスからアクセス obj.class_method_A() # インスタンスからアクセス #privateなクラスメソッドを呼び出し #testClass.__class_method_B() # クラスからアクセス:エラー testClass._testClass__class_method_B() # クラスからアクセス #obj.__class_method_B() # クラスからアクセス:エラー obj._testClass__class_method_B() # クラスからアクセス # publicなインスタンスメソッドを呼び出し obj.instance_method_A() # インスタンスからアクセス # privateなインスタンスメソッドを呼び出し #obj.__instance_method_B() # インスタンスからアクセス:エラー obj._testClass__instance_method_B() # インスタンスからアクセス
実行結果は以下になります。
コンストラクタを呼び出し class_variable_A = 1 class_variable_A = 1 __class_variable_B = 2 __class_variable_B = 2 instance_variable_A = 3 __instance_variable_B = 4 publicなクラスメソッドを呼び出し publicなクラスメソッドを呼び出し privateなクラスメソッドを呼び出し privateなクラスメソッドを呼び出し publicなインタンスメソッド privateなインタンスメソッド デストラクタを呼び出し