がじぇ

お金と家電とプログラミングのブログ

Pythonのclassmethodとstaticmethodの復習

おはようございます。

がじぇったー (@hackmylife7) | Twitter


です。

業務に必要になったのでPythonのclassmethodとstaticmethodの使い方について復習していきます。





CodeはUdemyの酒井さんの講座のものを使用させて頂いております。
自分もレビュー記事を書かせていただきましたが、ものすごく良い講座なので、おすすめです。
gadgeterkun.hatenablog.com



TL;DR(要約)

  • classmethodとstaticmethodを使う恩恵は可読性の向上や、codeの重複を防ぐこと
  • 上記メソッドを用いることで、インスタンス化を行わずにクラス内変数や定義された関数を使用することができる

通常のクラス内の関数の呼び出し方

通常のクラスの呼び出し方は以下の通り、インスタンス化を最初に行う。

class Person(object):
    kind = 'human'
    
    def __init__(self):
        self.x = 100

# インスタンス化し、変数を呼び出す
a = Person()
print(a)
print(a.what_is_your_kind())


クラス内部の関数を呼び出したければ、print(a.what_is_your_kind())とオブジェクトaの後ろに関数名をつければ呼び出せる。

classmethod

クラスメソッドを用いればオブジェクトを明示的に生成しない状態でもクラスメソッドを呼び出すことができる
また、クラス内で定義する関数の第一引数は"cls"を与える

class Person(object):
    kind = 'human'
    
    def __init__(self):
        self.x = 100

    # def what_is_your_kind(cls):
    #     return self.kind

    # classmethod
    @classmethod
    def what_is_your_kind(cls):
        return cls.kind


# インスタンス化
# a = Person()
# print(a)

# clsssmethodを用い、オブジェクトを生成しないで関数を呼び出す
print(Person.kind)
print(Person.what_is_your_kind())

staticmethod

staticmethodも同様にインスタンス化(オブジェクトを生成)せずにクラスの外から関数を呼び出すことができる

class Person(object):
    kind = 'human'
    
    def __init__(self):
        self.x = 100

    # def what_is_your_kind(cls):
    #     return self.kind

    # @classmethod
    # def what_is_your_kind(cls):
    #     return cls.kind

    @staticmethod
    def about(year):
        print('about human {}'.format(year))


# インスタンス化
# a = Person()
# print(a)

# clsssmethodを用い、オブジェクトを生成しないで関数を呼び出す
# print(Person.kind)
# print(Person.what_is_your_kind())


Person.about(1999)

classmethodとstaticmethodは何が違うのか?

・classmethodsでは、オブジェクトインスタンスのクラス=引数clsを、selfの代わりに最初の引数として渡す

・引数にクラス自身を渡しているため、クラス内で定義した変数を使うことができる。記事の例だとprint(Person.kind)とやっても"human"が結果に出力される

・また、classsmethodを使用する場合は、子クラスからclassmethodが呼び出された変数を使うと引数clsは子クラスになります。なので、print(Person.kind)とやってもクラス変数にアクセスできません。
その辺は以下の記事がとてもわかりやすいです。

クラスメソッドとスタティックメソッドについて - Qiita


・staticmethodsでは、selfもclsも最初の引数として暗黙的に渡されない 。
これらは、インスタンスまたはクラスから呼び出すことができることを除いて、単純な関数のように動作する。


参考記事(stackoverflow)のこの辺がわかりやすかったのだけど、selfも使わなくて良いし、メモリの節約にも繋がるよう。

1.It eliminates the use of self argument.

2.It reduces memory usage because Python doesn't have to instantiate a bound-method for each object instiantiated:

staticmethodは共通関数を集めてcommon.method()みたいな形で外から呼び出すと可読性も上がって良いかな。




参考
stackoverflow.com

stackoverflow.com