Cucco’s Compute Hack

コンピュータ関係の記事を書いていきます。

classmethodとクラス変数

クラスのインスタンスを作らずにクラスの関数を実行したい場合のメモ

クラス変数であればclassmethod内で参照できる。インスタンスを作ればクラス変数も変更できる。
classmethod内では、インスタンス変数は一切参照できない。(作ったインスタンスでclassmethodを実行しても)

classmethod を使う場合、第一引数を cls とすることが慣習らしいですが、以下のコードではselfとなっています。(検証コードとして、インスタンス変数を参照できる可能性を残すため)

コード
class myclass():
    # クラス変数
    val_class=1

    def __init__(self):
        # インスタンス変数
        self.val_inst=10

        # インスタンス生成時に、クラス変数を書き換え。
        __class__.val_class=100
    
    # 通常関数
    def print_inst(self):
        print(self.val_inst)
        print(__class__.val_class)
        print("\n")
    
    # classmethod
    # classmethodは、__init__以下で宣言したインスタンス変数にはアクセスできない。
    # インスタンスを作れば、クラス変数も変更できる。
    @classmethod
    def print_class(self):
        print(__class__.val_class)
        try:
            # val_instが初期化されていない可能性がある。
            print(self.val_inst)
        except Exception as e:
            print(e)
        print("\n")
        
if __name__ == "__main__":
    print("インスタンスを作らずに、classmethiodをコール")
    myclass.print_class()

    print("インスタンスを作る")
    x=myclass()

    print("インスタンスを作った後に、classmethiodをコール")
    myclass.print_class()

    print("インスタンスのなかのclassmethiodをコール")
    x.print_class()

    print("インスタンスのなかの通常関数をコール")
    x.print_inst()
実行結果
インスタンスを作らずに、classmethiodをコール
1
type object 'myclass' has no attribute 'val_inst'


インスタンスを作る
インスタンスを作った後に、classmethiodをコール
100
type object 'myclass' has no attribute 'val_inst'


インスタンスのなかのclassmethiodをコール
100
type object 'myclass' has no attribute 'val_inst'


インスタンスのなかの通常関数をコール
10
100