PyQオフィシャルブログ

Pythonのオンライン学習プラットフォームPyQのオフィシャルブログです

Pythonのクラスメソッド(@classmethod)とは?使いどころとメソッドとの違いを解説

f:id:nana_yu:20190131131835p:plain id:hirokiky です。

PyQ のスタンダードプランのお客様から、同じ質問がいくつかあったのでブログでもご紹介します。 PyQのスタンダードプランでは、PyQで学習中にプロのPythonプログラマーから質問への回答が受けられるサービスです。

pyq.jp

Pythonで クラス.メソッド() のように呼び出してるものは何?

Pythonで クラス.メソッド() のように呼び出せるものがあるのですが、これは何ですか?

これはPythonの「クラスメソッド」という機能です。 クラスにくっついている関数のようなもので、インタンス化していないクラスのものから呼び出せます。 以下のように、メソッドに @classmethod とつけることでクラスメソッドにできます。 このときメソッドの第一引数は self (インスタンス)でなくクラスそのもの(以下では cls )になります。

class A:
    @classmethod
    def my_cls_method(cls):
        return "Hello"


A.my_cls_method()  # "Hello" が返ります

クラスメソッドとメソッドの違いは?

Pythonのメソッドとクラスメソッドの違いは何ですか?

Pythonのメソッドは、クラスをインスタンスにしないと呼び出せませんが、クラスメソッドはクラスから直接呼び出します。

A.my_cls_method()

例えばDjangoのクラスベースビューの View.as_view() などがあります。

クラスメソッドと関数の違いは?

クラスメソッドと関数の違いは何ですか?

クラスメソッドは関数とそれほど大きな違いは無いと言えます。 ですが、以下の違いがあります。

  • 第一引数でクラスが取得できる
  • クラスの中にあるので、クラスをインポートすれば使える。

クラスメソッドの使い所は何ですか?

よく使われる例としては、そのクラスを作るメソッドを書くことです。 以下の例ではクラス Item と、Itemの情報をあるAPIから取得して返す retrieve_from_api というクラスメソッドを実装しています。

class Item:
    def __init__(self, id, name):
        self.id = id
        self.name = name

    @classmethod
    def retrieve_from_api(cls, id):
        res = requests.get(f"https://api.example.com/items/{id}")
        data = res.json()
        return cls(id, data["name"])

もちろんクラスメソッドを使わずに、以下のように関数でも書けます。

class Item:
    def __init__(self, id, name):
        self.id = id
        self.name = name


def retrieve_item(id):
    res = requests.get(f"https://api.example.com/items/{id}")
    data = res.json()
    return Item(id, data["name"])

このようにクラスメソッドと関数はそれほど大きな違いはありません。 ですが、 import Item としたときにまとめてインポートできるかどうかの違い(クラスの中でまとめて管理できるかどうかの違い)が大きいです。

Copyright ©2017-2018 BeProud Inc. All rights reserved.