質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

3回答

561閲覧

クラスメソッドの用途がわからない

yyjfou

総合スコア35

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

1クリップ

投稿2021/05/05 08:54

クラスメソッドの用途がわからないです。

Pythonのクラスメソッド(@classmethod)とは?使いどころとメソッドとの違いを解説
を見て、クラスメソッドの用途を勉強しています。

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"])

ならimport Item としたときにまとめてインポートできるが、

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"])

ならまとめてインポートできない、だから便利、と言う説明なのですが、なら

class Item: def __init__(self, id, name): self.id = id self.name = name def retrieve_from_api(cls, id): res = requests.get(f"https://api.example.com/items/{id}")      #以下省略

で良いのでは?と思います。
一番最後のようなコードではいけない理由を教えてください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

そのクラスのインスタンスを返す、ある種の特殊なコンストラクタとして使うのが、実用的な用途の一つだと思います(それがすべてではないと思いますが、一例として書いてみます)。

組み込み型のドキュメントにあるかな、と思って探したら、一番最初に見つかったのはこれでした。

classmethod int.from_bytes(bytes, byteorder, *, signed=False)
与えられたバイト列の整数表現を返します。

python

1>>> int.from_bytes(b'\x00\x10', byteorder='big') 216 3>>> int.from_bytes(b'\x00\x10', byteorder='little') 44096 5>>> int.from_bytes(b'\xfc\x00', byteorder='big', signed=True) 6-1024 7>>> int.from_bytes(b'\xfc\x00', byteorder='big', signed=False) 864512 9>>> int.from_bytes([255, 0, 0], byteorder='big') 1016711680

組み込み型 — Python 3.9.4 ドキュメント | int.from_bytes

こういうのは関数よりはメソッドにしたが使いやすいですし、コンストラクタに直接実装するとコードの見通しが悪くなります。ということでクラスメソッドが適当な感じがします。


ということは質問者さんの参考にしているページにも書いてあるな……とあとから見て思ったので、ちょっと追記。

クラスメソッドはクラス自身を第一引数に取れます。なので、clsを使って何らかの処理を行うようなクラスメソッドであれば、サブクラスから呼び出した場合も適切に機能することが期待できる、というのは、関数にはないメリットと言えると思います。

python

1class Hoge: 2 ほにゃらら 3 4class Fuga: 5 @classmethod 6 def from_hoge(cls, hogeobj): 7 hogeobjを加工したりとか色々する 8 return cls(ほにゃらら)

という感じの定義があったときに、

python

1class FugaX(Fuga): 2 ほにゃらら 3 4class FugaY(Fuga): 5 ほにゃらら 6 7class FugaZ(Fuga): 8 ほにゃらら 9 10hoge = Hoge() 11fx = FugaX.from_hoge(hoge) # fxはFugaXのインスタンスになる 12fy = FugaY.from_hoge(hoge) # fyはFugaYのインスタンスになる 13fz = FugaZ.from_hoge(hoge) # fzはFugaZのインスタンスになる

ということができるという理屈です。

投稿2021/05/05 09:17

編集2021/05/05 09:32
hayataka2049

総合スコア30933

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yyjfou

2021/05/05 11:57

ありがとうございます。ちょっと質問させてください。「こういうのは関数よりはメソッドにしたが使いやすいです」とありますが、関数=メソッドではないのでしょうか?詳細に言うと関数と呼ぶ言語とメソッドと呼ぶ言語に分かれていると言う認識です。 また「なので、clsを使って何らかの処理を行うようなクラスメソッドであれば、サブクラスから呼び出した場合も適切に機能することが期待できる」とありますが、clsを使って何らかの処理を行うようなクラスメソッドとは例えばどんな場合ですか?またサブクラスとは何を指していますか?
yyjfou

2021/05/05 12:42

サブクラスは継承したクラスのことですよね!すみません
hayataka2049

2021/05/06 02:53

関数=メソッドではありません。それぞれ存在します。 clsを使うケースとしては、回答のコードをご確認ください。
yyjfou

2021/05/11 07:33

ありがとうございます、勉強になります
guest

0

一番最後のようなコードではいけない理由を教えてください。

このように定義すると、そのインスタンスメソッドを呼び出すために、少なくともひとつのインスタンスオブジェクトを作っておかなければならず、それは使いにくいからです。

本題ではありませんが

Pythonのクラスメソッド(@classmethod)とは?使いどころとメソッドとの違いを解説というサイトはPythonのことをわかっている人が書いているとは思えないですね。

クラスをインポートすれば使える。

importするのは、モジュールやパッケージです。クラスをインポートするという言葉遣いは誤解を与えるので望ましくありません。

そのクラスを作るメソッドを書くことです。

クラスを作るメソッドは存在しますが、ここに書かれている例はクラスを作るメソッドではありません。

結論:こういうサイトは参考にしない方が良いですよ。

投稿2021/05/05 09:21

ppaul

総合スコア24666

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

一番最後のようなコードではいけない理由を教えてください。

インスタンスメソッドは、Itemのインスタンスを作らないと呼び出せません。クラスメソッドなら、インスタンスを用意しなくてもいきなりItem.retrieve_from_apiとできます。

投稿2021/05/05 08:59

maisumakun

総合スコア145121

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問