はじめに
初学者を脱しつつある者を襲う贅沢な悩み
クラスについて学ぼうと多くの解説サイトを訪れたが、ほとんどの解説サイトは私を満足させなかった。
Flaskの学習をしたときも同様だった。Pythonを一から学ぶ人向けの教材ならともかくFlaskやクラスを学ぼうとしている人にHello worldレベルのプログラムを見せられても物足りなさを感じてしまうのは当然のことだ。
何とかしっくり来たのはこちらの個人サイトだった。
クラスの利便性に気付く
夏休みの自由研究としてディープラーニングを駆使したアプリを作った。仕様を充実させていくにつれ関数に送る引数がどんどん増えていき、収拾がつかなくなってしまった。複数の変数を一つの辞書に登録することも考えたが、どうも違う。こんなとき先達たちはどうしていただろうか。
そう考えて思い出したのがクラスだった。
九割方できていたコードをほとんど見直すことになってしまいそちらの完成は延期となった。そのかわりクラスを意識したちょっとしたプログラムをゼロから作った。
クラスの実装と改良
作ったゲームはこんな感じ。なぜこんなのを作ったかは今となってはわからない。
最初は「ちょっとしたプログラム」だから隕石なんて赤丸でいいじゃんと思っていたのだが、スプライト関数を自作しておいてそれを使わないなんてとんでもない!とどんどん凝っていってしまった。
改善前
最初はスコープの扱いがよくわからず、次のようなグローバル変数頼みのコードを書いていた。
class Game():
def __init__(self):
BeamとMeteorを扱うのでクラス内でグローバル変数beamとmeteorsが使われている
class Beam():
def __init__(self):
GameとMeteorを扱うのでクラス内でグローバル変数gameとmeteorsが使われている
class Meteor():
def __init__(self):
Gameを扱うのでクラス内でグローバル変数gameが使われている
def main():
ループ内で
meteors.append(Meteor())
など
# ここ、グローバル
game = Game()
beam = Beam()
meteors = []
if __name__ == "__main__":
main()
改善後
だが、それでは駄目だと考え直し、次のように作り直した。これによりグローバル変数を使うことなく、またクラス間の主従関係(?)もわかりやすくなった。
ここに至るまでに4~5回は全体的なコードを書き直している。これもまた経験だ。
class Game():
def __init__(self):
self.meteors = []
self.beam = Beam(self)
class Beam():
def __init__(self, game):
略
class Meteor():
def __init__(self, game):
略
def main():
game = Game()
ループ内で
game.meteors.append(Meteor(game))
など
if __name__ == "__main__":
main()
もう一つの課題
きれいなコードを書きGitHubに公開することも夏休みの課題の一つだった。だから今回はいろいろがんばったのだが、肝心のGitHubへのコミットがうまくいかなかった。もう一度一から勉強しなおさなくては。
無理やっこアップロードしたのがこちら。
終わりに
「ちょっとしたプログラム」に1か月以上かかってしまった。夏休みに作っていたメインの作品の完成はいつになるのだろう。