1
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

クラスメソッドの使いどころを考えたけど分からなかった

Last updated at Posted at 2019-07-08

目的

  • クラスメソッドの効果的な使い方を考える
  • 中の人が初めてクラスメソッドを学んだので、使い方の備忘録として記述する

ポイント

  • classmethodはインスタンス化しないでクラス内の要素にアクセスできる
  • @classmethodでクラスメソッドを修飾する
  • classmethodは引数に自分自身のクラスを持ち、自分自身をclsと記述する

中の人が考えたclassmethodの使いどころ

  • 以下の状況が重なったとき
    • クラスが何かのソースを参照したデータを持っている
    • ソースが変わったときに別のクラスを生成したい
    • ソースごとにサブクラスを定義するのは冗長である
    • (インスタンス生成前にクラスにデータを持たせたい)

## 結論
今回の例はインスタンス生成時にソースを指定するコンストラクタを書いておけばいいんジャマイカ・・・
中の人の技量が足りなかったため、効果的な使い方を提示するに至らなかった。

また、下記コードは意図しない動作になっていることが判明しました。
中の人のレベルが上がったら修正します。
誤解誤認されませんよう、お気をつけください。

コード

データソースの準備

sample_data_for_clasmethod1.csv
0,10
1,20
2,30
3,40
sample_data_for_clasmethod2.csv
0,1
1,2
2,3
3,4

クラスの定義

  • pandasで読み込んだdfを保持するcls.dataを有するクラス
    • クラスメソッドで指定したデータソースをdfにしてcls.dataに保持する機能を持たせる
    • インスタンスメソッドで各列の合計を計算する機能を持たせる
classmethod_for_learning.py

import pandas as pd

class SampleData:

    data_kind = 'CSV'

    def __init__(self, data_name):
        """ 初期化 """
        self.data_name = data_name

    def show_sum_1st_column(self):
        return self.data.iloc[:,0].sum()
    
    def show_sum_2nd_column(self):
        return self.data.iloc[:,1].sum()


    @classmethod
    def load_data_source(cls, data_path):
        cls.data = pd.read_csv(data_path)
        return cls

実行コード

  • プリント関数内の文書のように動作確認を行うコード
  • データのソースはsample_data_for_clasmethod1.csv
  • データソース指定後は、クラスオブジェクトをsample1と定義する
main1.py

print('sample1を与えたクラスメソッドの動作を確認する')
sample1 = SampleData.load_data_source('sample_data_for_clasmethod1.csv')
print(sample1.data_kind)
print(sample1.data)
print()
sample1_ins = sample1('sample1_dataを与えたクラスで生成したインスタンスであるsample1_ins')
print(sample1_ins.data_name)
print('sample1_insのデータを確認する(クラスメソッドから呼び出す)')
print(sample1_ins.data)
print('sample1_insのメソッドを確認する')
print('0列目合計', sample1_ins.show_sum_1st_column())
print('1列目合計', sample1_ins.show_sum_2nd_column())
  • 同様にデータのソースをsample_data_for_clasmethod2.csvに変更して実行
  • データソース指定後は、クラスオブジェクトをsample2と定義する
main2.py
print('sample2を与えたクラスメソッドの動作を確認する')
sample2 = SampleData.load_data_source('sample_data_for_clasmethod2.csv')
print(sample2.data_kind)
print(sample2.data)
print()
sample2_ins = sample2('sample2_dataを与えたクラスで生成したインスタンスであるsample2_ins')
print(sample2_ins.data_name)
print('sample2_insのデータを確認する(クラスメソッドから呼び出す)')
print(sample2_ins.data)
print('sample2_insのメソッドを確認する')
print('0列目合計',sample2_ins.show_sum_1st_column())
print('1列目合計',sample2_ins.show_sum_2nd_column())

実行結果

  • クラス内にデータを保持していることが確認できた
  • クラス内のデータをクラスメソッドで変更できた。
  • データのソースが異なるクラスを、それぞれ別名のクラスオブジェクト(sample1とsample2)に定義できた
  • インスタンス化してもクラス内のデータは保持された
  • それぞれのインスタンスのメソッドにより異なるソースの処理を行えた
sample1を与えたクラスメソッドの動作を確認する
CSV
   0  10
0  1  20
1  2  30
2  3  40

sample1_dataを与えたクラスで生成したインスタンスであるsample1_ins
sample1_insのデータを確認する(クラスメソッドから呼び出す)
   0  10
0  1  20
1  2  30
2  3  40
sample1_insのメソッドを確認する
0列目合計 6
1列目合計 90



sample2を与えたクラスメソッドの動作を確認する
CSV
   0  1
0  1  2
1  2  3
2  3  4

sample2_dataを与えたクラスで生成したインスタンスであるsample2_ins
sample2_insのデータを確認する(クラスメソッドから呼び出す)
   0  1
0  1  2
1  2  3
2  3  4
sample2_insのメソッドを確認する
0列目合計 6
1列目合計 9

参考にさせていただきました

PythonエンジニアによるPython3学習サイト

1
4
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?