class Student:
def __init__(
self, name: str, japanese_point: int, arithmetic_point: int, english_point: int
) -> None:
self.name: str = name
self.japanese_point: int = japanese_point
self.arithmetic_point: int = arithmetic_point
self.english_point: int = english_point
self.avg_point: float
# 平均点計算
def avg(self) -> None:
total_point: int = (
self.japanese_point + self.arithmetic_point + self.english_point
)
self.avg_point = round(total_point / 3, 1) # 小数点第1位以下四捨五入
# 平均点表示
def show_avg(self) -> None:
print(f"{self.name}さんの平均点は{self.avg_point}点です。")
def main():
# 田中さんの処理
tanaka_st = Student("田中", 65, 39, 87)
tanaka_st.avg()
tanaka_st.show_avg()
# 佐藤さんの処理
satou_st = Student(
name="佐藤", japanese_point=92, arithmetic_point=55, english_point=36
) # この書き方の方がわかりやすい
satou_st.avg()
satou_st.show_avg()
if __name__ == "__main__":
main()
田中さんと佐藤さんの平均点を表示するプログラムです。
class内で平均点を計算し、その平均点を表示するという処理です。
コンストラクタ
def __init__
は、初期値を設定する場所。
Student("田中", 65, 39, 87)
でname
、japanese_point
、arithmetic_point
、english_point
の値をクラスの引数に渡します。
def __init__
の中でそれぞれの値をセットしています。
引数selfをお忘れなく!
pythonではclass内の関数の引数に必ずself
を含めます。
def avg(self):
のように。
これは__init__
で初期値を代入したself.
の変数を継承しています。
何も引数で渡すものがなくても必ずself
を渡します。
あるあるとして、self
を渡すのを忘れていてエラーがでること。
self.の値について
コンストラクタで設定した値(self.の値)がclass内の他の関数の中で値が変わった場合、そのまま継承されていきます。
今回だとself.avg_point
はコンストラクタdef __init__
の中では、定義だけで値は何も代入されていません。
avg関数
の中でself.avg_point
に平均点が代入されました。
show_avg関数
でself.avg_point
を表示していますが、avg関数
で代入した数値がそのまま表示されています。
self.
の変数はclass内に限り、関数をまたいで使い回しができます。
もし関数だけで組んだら
↑のクラスをすべて関数だけでやった場合。
def avg(
name: str, japanese_point: int, arithmetic_point: int, english_point: int
) -> float:
total_point: int = japanese_point + arithmetic_point + english_point
avg_point: float = round(total_point / 3, 1) # 小数点第1位以下四捨五入
return avg_point
def show_avg(name: str, avg_point: float) -> None:
print(f"{name}さんの平均点は{avg_point}点です。")
def main():
# 田中さんの処理
name: str = "田中"
japanese_point: int = 65
arithmetic_point: int = 39
english_point: int = 87
avg_point: float = avg(name, japanese_point, arithmetic_point, english_point)
show_avg(name, avg_point)
# 佐藤さんの処理
name = "佐藤"
japanese_point = 92
arithmetic_point = 55
english_point = 36
avg_point = avg(name, japanese_point, arithmetic_point, english_point)
show_avg(name, avg_point)
if __name__ == "__main__":
main()
処理自体が少ないのでそんなに行数は変わりませんが、多くなってきた場合、関数だけで書くと膨大な行数になり同じことを連続して書かないといけなくなったりします。
あと、関数だけだと毎回引数で渡す必要が出てきます。
クラスの場合だと、コンストラクタで管理されているので、self
だけ渡せばOKになります。
アノテーションをつけよう!
classに限ったことではないのですが、アノテーションをつけた方が、みやすいしあとあとのメンテナンス性も上がります。
チーム開発のときでも他の人がみて一目でどんなデータが入っているのかがわかります。
基本的に変数定義と関数の引数、返り値につけます。
# 変数定義
name: str = "田中"
point: int = 65
# 関数の引数
def show_avg(name: str, avg_point: float):
# これだと引数の中に何が入っているのかわかりにくい。
def show_avg(name, avg_point):
name
はなんとなく文字が入ってるんだろうなと想像できますが、avg_point
の場合はpointなので数値なんだろうけどint型なのかfloat型なのかまた他の型なのかがパッと見わからない。
なのでアノテーションをつけることでわかりやすくなる。
# 関数の返り値
def avg(引数) -> float:
関数内でreturn
で何が返っているのか確認しなくても、float型が返っているのがわかる。