Python

PythonのClassをつかってみる

こんにちは Tomoです。

今回はPythonのClassをつかってみたいと思います。

事前準備

前回の続きとなります

以下の内容を確認してください。


クラスを定義

前回list型で管理していた値をクラスで管理したいと思います。

クラスとは何か?といわれると説明が難しいですね、とりあえず進めます。

    
class CalendaEventClass():

    def ___init___(self):
        self.summary   = none
        self.stat_date = none
        self.end_date  = none
    

class CalendaEventClass():

classであることを宣言して、名前を「CalendaEvent」としてClassをつけます。「:」を忘れないように。

___init___を記載しています。これはクラスを呼び出す(インスタンス生成)したときに最初によばれるものです。

インスタンス生成も難しいので、ここでは省略して進めます。

そのあとにsummary、stat_date、end_dateを記載しています。この時noneを使って初期化をしています。

とりあえずは、なんとなくでおぼえてもらうといいかもしれません。

これでクラスを定義しました。

read_calendar_zipの関数を修正

つぎに、read_calendar_zipの関数でつかっていたstat_date_listを置き換えていきます。

    
def read_calendar_zip():
    """
    zip形式のカレンダーを取得してlistに格納します.
    """
    with zipfile.ZipFile(CALENDAR_ZIP_FILE_PATH) as cal_zip:
        with cal_zip.open(CALENDAR_FILE_NAME) as cal_file:
            jst = datetime.timezone(datetime.timedelta(hours=+9), 'JST')

            cal_eve_list = []
            for line in cal_file:
                 line_decode = line.decode('utf-8')
                 line_decode = line_decode.rstrip('\r\n')

                 # イベントの開始(BEGIN:VEVENT)を探す
                 if 'BEGIN:VEVENT' in line_decode:
                     cd = CalendaEventClass()
                     print(line_decode)

                 # 開始時間(DTSTART)を探す
                 if 'DTSTART:' in line_decode:
                     dt_start = line_decode.split(':')
                     dt_start_time = dateutil.parser.parse(dt_start[1]).astimezone(jst)
                     cd.stat_date = dt_start_time
                     print(dt_start_time.strftime(FORMAT_DATE_TIME))

                 # 終了時間(DTEND)を探す
                 if 'DTEND:' in line_decode:
                     dt_end = line_decode.split(":")
                     dt_end_time = dateutil.parser.parse(dt_end[1]).astimezone(jst)
                     cd.end_date = dt_end_time
                     print(dt_end_time.strftime(FORMAT_DATE_TIME))

                 # タイトル(SUMMARY)を探す
                 if 'SUMMARY:' in line_decode:
                     summary = line_decode.split(':')
                     cd.summary  = summary[1]
                     print(summary[1])

                 # イベントの終了(END:VEVENT)
                 if 'END:VEVENT' in line_decode:
                     cal_eve_list.append(cd)
                     print(line_decode)

            return cal_eve_list
    

どこを変えたか分かり難いですが、繰り返し構文の前で『cal_eve_list = []』を宣言してます。

リストをやめたのでは?と突っ込みもありそうですが、今回は先ほど作成したクラスをこのリストに格納するイメージです

イベント開始で「cd = CalendaEventClass()」を記載しています。これがクラスの呼び出しでインスタンス生成をしています。

開始時間時間のところでは、「stat_date_list.append(dt_start_time)」にかえて「cd.end_date = dt_end_time」を記載しています。

他も同様です。

ポイントは、インスタンス生成した物(オブジェクト)の中にある開始時間に値を代入している感じです。

クラス、オブジェクト、インスタンス、プロパティ、メソッドとまずはこの言葉の違いがわかると後々良いかもしれません。

まあ、おぼえなくてもとりあえず動けばいいので進めます。

イベントの終了で、「cal_eve_list.append(cd)」「cd」オブジェクトをlistに詰めてます。

最後に「return cal_eve_list」でこの関数の呼び出し元にlistを返しています。

つぎに、read_calendar_zipの関数でつかっていたstat_date_listを置き換えていきます。

呼び出し元を修正します。

    
# 関数呼び出し
cal_eve_list = read_calendar_zip()
print(cal_eve_list)
#write_attendance(cal_eve_list)
    

関数の戻り値をcal_eve_listに代入します。

listをprintで出力します。

書き込みをコメントアウトして動かないようにします。

では実行します。

    
[
    <__main__.CalendaEventClass object at 0x0000025505C20E48>,
    <__main__.CalendaEventClass object at 0x000002550628C248>,
    <__main__.CalendaEventClass object at 0x0000025506230408>
]
    

実行した結果を改行して表示します。

listに3つのオブジェクトがはいっていることがわかります。

write_attendanceの関数を修正

つぎに、write_attendanceの関数でつかっていたstat_date_listを置き換えていきます。

    
def write_attendance(cal_eve_list):
    """
    勤怠データを出力します.
    """
    work_book = openpyxl.Workbook()
    work_sheet = work_book.active

    count = 0
    for cd in cal_eve_list:
        count = count + 1
        print('----------')
        print(cd.summary)
        print(cd.stat_date.strftime(FORMAT_DATE))
        print(cd.stat_date.strftime(FORMAT_HM))
        print(cd.end_date.strftime(FORMAT_DATE))
        print(cd.end_date.strftime(FORMAT_HM))
        print(cd.end_date - cd.stat_date - datetime.timedelta(hours=1))

        work_sheet.cell(count, 1).value = cd.summary
        work_sheet.cell(count, 2).value = cd.stat_date.strftime(FORMAT_DATE)
        work_sheet.cell(count, 3).value = cd.stat_date.strftime(FORMAT_HM)
        work_sheet.cell(count, 4).value = cd.end_date.strftime(FORMAT_HM)
        work_sheet.cell(count, 5).value = cd.end_date - cd.stat_date - datetime.timedelta(hours=1)

        work_book.save(ATTENDANCE_FILE_PATH)
    

上記のように置き換えます。

「write_attendance(cal_eve_list)」先ほどprintしたlistを引数に渡します。

「for cd in cal_eve_list」リストのオブジェクトをひとつづつ繰り返します。

「count = count + 1」で繰り返す回数分1追加します。

「work_sheet.cell(count, 1).value = cd.summary」

短くなりました。count + 1していましたが、countだけの記載にしています。

cd.summaryこれでオブジェクトの中の値を取得しています。

あとの記述も同様に修正します。

最後に関数の呼び出しのコメントを外します。

    
# 関数呼び出し
cal_eve_list = read_calendar_zip()
print(cal_eve_list)
write_attendance(cal_eve_list)
    

実行して表計算ソフトの出力結果を確認してください。

まとめ

今回はlistからクラスにしました。

クラスの難しいところは、何をどこまでクラスにするのかが難しいです。

今回は値だけをクラスとして定義していますが、ほかにもクラスの方法はあると思います。

次回は繰り返しの予定登録でデータの読み込みを行いたいと思います。

最後にソースを記載します。

    
import zipfile
import datetime
import dateutil.parser
import openpyxl

# カレンダーZIPファイル
CALENDAR_ZIP_FILE_PATH = 'D:\\python_workspace\\imput_data\\{Google アカウント}@gmail.com.ical.zip'
# カレンダーICSファイル
CALENDAR_FILE_NAME = '{xxxxxxxx}@group.calendar.google.com.ics'
# 勤怠管理ファイル
ATTENDANCE_FILE_PATH = 'D:\\python_workspace\\output_data\\test.xlsx'

class CalendaEventClass():

    def ___init___(self):
        self.summary   = none
        self.stat_date = none
        self.end_date  = none

def read_calendar_zip():
    """
    zip形式のカレンダーを取得してlistに格納します.
    """
    with zipfile.ZipFile(CALENDAR_ZIP_FILE_PATH) as cal_zip:
        with cal_zip.open(CALENDAR_FILE_NAME) as cal_file:
            jst = datetime.timezone(datetime.timedelta(hours=+9), 'JST')

            cal_eve_list = []
            for line in cal_file:
                 line_decode = line.decode('utf-8')
                 line_decode = line_decode.rstrip('\r\n')

                 # イベントの開始(BEGIN:VEVENT)を探す
                 if 'BEGIN:VEVENT' in line_decode:
                     cd = CalendaEventClass()
                     print(line_decode)

                 # 開始時間(DTSTART)を探す
                 if 'DTSTART:' in line_decode:
                     dt_start = line_decode.split(':')
                     dt_start_time = dateutil.parser.parse(dt_start[1]).astimezone(jst)
                     cd.stat_date = dt_start_time
                     print(dt_start_time.strftime(FORMAT_DATE_TIME))

                 # 終了時間(DTEND)を探す
                 if 'DTEND:' in line_decode:
                     dt_end = line_decode.split(":")
                     dt_end_time = dateutil.parser.parse(dt_end[1]).astimezone(jst)
                     cd.end_date = dt_end_time
                     print(dt_end_time.strftime(FORMAT_DATE_TIME))

                 # タイトル(SUMMARY)を探す
                 if 'SUMMARY:' in line_decode:
                     summary = line_decode.split(':')
                     cd.summary  = summary[1]
                     print(summary[1])

                 # イベントの終了(END:VEVENT)
                 if 'END:VEVENT' in line_decode:
                     cal_eve_list.append(cd)
                     print(line_decode)

            return cal_eve_list

def write_attendance(cal_eve_list):
    """
    勤怠データを出力します.
    """
    work_book = openpyxl.Workbook()
    work_sheet = work_book.active

    count = 0
    for cd in cal_eve_list:
        count = count + 1
        print('----------')
        print(cd.summary)
        print(cd.stat_date.strftime(FORMAT_DATE))
        print(cd.stat_date.strftime(FORMAT_HM))
        print(cd.end_date.strftime(FORMAT_DATE))
        print(cd.end_date.strftime(FORMAT_HM))
        print(cd.end_date - cd.stat_date - datetime.timedelta(hours=1))

        work_sheet.cell(count, 1).value = cd.summary
        work_sheet.cell(count, 2).value = cd.stat_date.strftime(FORMAT_DATE)
        work_sheet.cell(count, 3).value = cd.stat_date.strftime(FORMAT_HM)
        work_sheet.cell(count, 4).value = cd.end_date.strftime(FORMAT_HM)
        work_sheet.cell(count, 5).value = cd.end_date - cd.stat_date - datetime.timedelta(hours=1)

        work_book.save(ATTENDANCE_FILE_PATH)


# 関数呼び出し
cal_eve_list = read_calendar_zip()
# print(cal_eve_list)
write_attendance(cal_eve_list)
    

コメント

0 件のコメント:

コメントを投稿

コメントをお待ちしています。