これまで初歩的なプログラミングのステップとして以下の記事でPythonの基本的な使い方を解説してきました。
しかしながらより高度で複雑なアプリケーションをしたいとなるとより他の機能を知る必要が出てきます。
この記事ではより高度なアプリケーションを開発するために必要なPython知識を解説します。
目次
辞書(Dictionary)
辞書は以前ご紹介した配列と同様、データの塊を管理する仕組みです。
配列のような順番管理ができませんが、以下の例のようにキー指定して管理できます。
#基本的な使い方 fruit_list = { "apple" : 200, "orange" : 150, "banana" : 300 } print(fruit_list["apple"]) # 200 を返す #入れ子にもできます。 goods_list = { "vegetable" : { "cabbage" : 320, "carrot" : 50 }, "fruit" : fruit_list, } print(goods_list["fruit"]["banana"]) #追加もできます。 fruit_list["pineapple"] = 500 print(fruit_list["pineapple"]) # 500 #このような使い方で繰り返しによる展開もできます。 for name in fruit_list: print(name) print(fruit_list[name]) #500 #apple #200 #orange #150 #banana #300 #pineapple #500
関数
関数は処理の塊として定義することで何度も再利用できるものです。
# 使い方 def greeting(name, age) : print("こんにちは私の名前は" + name + "です。" + age + "歳です。") greeting("みやう", "30") greeting("やまだ", "50") #こんにちは私の名前はみやうです。30歳です。 #こんにちは私の名前はやまだです。50歳です。 # 関数は返り値を返すこともできます。 # 返り値つきの関数を使って基本編で使ったFizzBuzzアプリを関数利用で作ってみます。 def getFizzBuzzString(number): output = str(number) if number % 3 == 0: output = output + "Fizz" if number % 5 == 0: output = output + "Buzz" return output; value = 0 while value <= 100: #出力します message = getFizzBuzzString(value) print(message) value = value + 1 # #0FizzBuzz #1 #2 #3Fizz #4 #5Buzz #6Fizz #7 #8 #9Fizz
クラスとオブジェクト
配列や辞書がデータの塊を管理する機能、関数が処理の塊を管理をする機能でした。
クラスはデータと処理両方を塊として管理するための機能です。
クラスの機能を使って型をつくることで、オブジェクトという塊を作成することができます。
クラスを使ってモンスターを生み出してバトルするアプリケーションを作ってみましょう。
# クラスはオブジェクト化したいもの型を定義することができます class Monster: # クラスに所属するデータを定義します。 # モンスターという型のクラスのため、モンスター名とHP、攻撃力を定義します。 # 現在仮の値をいれていますが、のちに紹介するコンストラクタでデータを上書きします name = "" life_point = 20 atack_point = 5 # クラスに所属する処理を定義します。defを使いますが一般に関数とは言わず、メソッドと呼びます。 # __init__という処理はコンストラクタといい、クラス初期化の時に実行される処理を記載します。 # self は自分自身のオブジェクトを指します。メソッド実行時は省略されます。 def __init__(self, name, life_point, atack_point): self.name = name self.life_point = life_point self.atack_point = atack_point # 攻撃をするために攻撃ポイントを取得するメソッドです # このメソッドから値を取り出して攻撃対象にダメージを与えます。 def atack(self) : return self.atack_point # ダメージを受けるメソッドです # 攻撃対象のモンスターから受け取った攻撃力をこのメソッドに渡して残りの体力を計算します。 def damage(self, point) : self.life_point = self.life_point - point if self.life_point < 1: self.life_point = 0 print(self.name + "は倒れた") def getStatus(self): return "モンスター名:" + self.name + " 攻撃力:" + str(self.atack_point) + " HP:" + str(self.life_point) #@staticmethod をつけるとクラスをオブジェクト化せずに実行できます。 @staticmethod def getSlime() : return Monster("スライム", 5, 1) # モンスターをクラスから2体のオブジェクトとして作ってみます。 goblin = Monster("ゴブリン", 10, 2) dragon = Monster("ドラゴン", 20, 15) # それぞれのステータスを確認して見ます。 message = goblin.getStatus() print(message) message = dragon.getStatus() print(message) #モンスター名:ゴブリン 攻撃力:2 HP:10 #モンスター名:ドラゴン 攻撃力:5 HP:20 # ゴブリンがドラゴンを攻撃してみます。 dragon.damage(goblin.atack()) # ドラゴンのライフポイントが減りました message = dragon.getStatus() print(message) #モンスター名:ドラゴン 攻撃力:5 HP:18 # ドラゴンがゴブリンを攻撃してみます。ゴブリンがライフゼロになり倒れます。 goblin.damage(dragon.atack()) message = goblin.getStatus() print(message) #ゴブリンは倒れた #モンスター名:ゴブリン 攻撃力:2 HP:0 # staticメソッドはこのようにクラスのメソッドをオブジェクト化しなくても使うことができます slime = Monster.getSlime() print(slime.getStatus()) #モンスター名:スライム 攻撃力:1 HP:5
クラスを使うことでデータや処理を塊ベースで処理することができるようになるため、設計がしやすくなったり、複数人開発が用意になるメリットがあります。
そのため、大規模で複雑なアプリケーションほど、クラスを利用することが多いです。
このようにクラスを作ってオブジェクトを作っていく開発のことをオブジェクト指向と呼びます。
ファイル分割
大規模なアプリケーションになるほど処理が多くなり、プログラムコード行数が長くなります。
こういう時はファイル分割を行います。
今回は前回作ったモンスターをバトルさせるプログラミングを以下3つのファイルに分割してみましょう。
./main.py ./battle.py ./monster.py
#main.py #このfrom importがポイントで各ファイルのメソッドやクラスを取得できます。 from battle import atack from monster import Monster goblin = Monster("ゴブリン", 10, 2) dragon = Monster("ドラゴン", 20, 5) atack(goblin, dragon)
#battle.py def atack(atack_monster, damage_monster): message = atack_monster.getStatus() print(message) message = damage_monster.getStatus() print(message) print("攻撃実行") damage_monster.damage(atack_monster.atack()) message = atack_monster.getStatus() print(message) message = damage_monster.getStatus() print(message)
#monster.py class Monster: name = "" life_point = 20 atack_point = 5 # コンストラクタ クラス初期化の時に実行される def __init__(self, name, life_point, atack_point): self.name = name self.life_point = life_point self.atack_point = atack_point # クラスに所属する関数(=メソッド)を定義します。 # 攻撃をするために攻撃ポイントを取得するメソッドです def atack(self) : return self.atack_point # ダメージを受けるメソッドです def damage(self, point) : self.life_point = self.life_point - point def getStatus(self): return "モンスター名:" + self.name + " 攻撃力:" + str(self.atack_point) + " HP:" + str(self.life_point) #@staticmethod をつけるとクラスをオブジェクト化せずに実行できます。 @staticmethod def getSlime() : return Monster("スライム", 5, 1)
main.pyのimport-fromがポイントでこのように定義して外のファイルの関数やクラスを取得します。
% python3 main.py モンスター名:ゴブリン 攻撃力:2 HP:10 モンスター名:ドラゴン 攻撃力:5 HP:20 攻撃実行 モンスター名:ゴブリン 攻撃力:2 HP:10 モンスター名:ドラゴン 攻撃力:5 HP:18
外部のライブラリを用いてWEBサーバーを作ってみる
最後にWEBサーバーを作ってみましょう。
WEBサーバーを作る場合、Pythonの処理をゼロから作るのは大変なのでFlaskという外部のOSSライブラリを今回利用してみましょう。
外部のOSSを使うことはライセンスやセキュリティに注意が必要ですが、開発をより便利にスムーズに行うことができます。
以下のコマンドを打つことでFlaskのライブラリをインストールすることができます。
# macの場合 $ python3 -m pip install Flask # windowsの場合 $ py -m pip install Flask
pythonコマンド以降の「-m pip install <ライブラリ名>」を行うことで外部のライブラリをインストールできます。<
インストールできたら以下のように書いてみましょう。
一部みたことがない書き方がありますが、初心者のうちはおまじないで覚えてしまって問題ありません。
from flask import Flask app = Flask(__name__) # @app.routeにアクセスするパスを定義します @app.route('/hello') def hello(): message = "Hello" return message @app.route('/goodmorning') def goodmorning(): message = "Good Morning" return message ## メインプロセスの時のみサーバーアプリケーションを実行します。 ## 初心者のうちはおまじないの認識で問題ありません。 if __name__ == "__main__": app.run()
書き終わったら実行してみましょう。
# 実行例 # これまでのプログラミングと違い、自動で終了しません。 # 終了する場合Ctrl + Cを押してください。 % python3 server.py * Serving Flask app "server" (lazy loading) * Environment: production WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. * Debug mode: off * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit) 127.0.0.1 - - [04/Nov/2021 01:23:28] "GET /goodmorning HTTP/1.1" 200 -
「http://127.0.0.1:5000/hello」や「http://127.0.0.1:5000/goodmorning」にアクセスしてみましょう。各関数に記載した文字列が表示されるようになります。
今回はFlaskというWEBサーバーのライブラリを使いましたが、他にもさまざまな便利ライブラリがありますので探してみましょう。
終わりに
以前書いた記事に引き続きPython学習の参考になれば幸いです。
最後まで読んでいただきありがとうございました。
Photo by Artem Sapegin on Unsplash