こんにちは、みやびのです。
今回は、「Pythonソースコードの読み方」というテーマでお話しします。
ソースコードを読むというといきなりコードを読み始まる方がいるかもしれませんが、初心者の場合ただコードを読むのはあまりおすすめしません
まずはプログラムを動かして、コードとの対応関係を見ていきましょう。
本記事では、Python入門者がソースコードを読むための具体的な手順について紹介します

Pythonのソースコードを読む前にやること~実際に動かそう~

スイッチ
いきなりソースコードを読みたくなるかもしれませんが、プログラムの動きがわからないままソースコードを見ても1つ1つの処理が理解しにくいです
まずはプログラムを実際に動かして機能を理解しましょう。
事前に動かしておくことには以下のメリットがあります。

・プログラムの目的を理解しやすい
・ソースコードを理解しやすい

プログラムの目的を理解しやすい

事前に動かしておけばプログラムの目的(何のためのプログラムか)が理解しやすいです。また、ボタンや文字や画像の役割も理解しやすくなります。
何のためのプログラムかわからないままソースコードを読んでいても理解は進みません。
まずはプログラムを動かして目的や文字や画像などの役割を理解しておきましょう

ソースコードを理解しやすい

初心者がソースコード読んだだけで実際の動きを理解することは難しいです。頭の中にプログラムが動くイメージがないからです。
事前に動きを知っておけば、「これはあの機能を実現するためのものではないか?」のようにソースコードから処理を予測することができます。

Pythonのソースコードを読む手順

Todo
以下のプログラムは天気をGUI表示するプログラムです。

import tkinter
import requests
import json
# 今日の天気を表示
def today_weather():
    update_weather(0)
# 明日の天気を表示
def yesterday_weather():
    # ラベルにメッセージを設定
    update_weather(1)
# 今日の天気を表示
def update_weather(date_num):
    # ラベルにメッセージを設定
    t = display_weather(date_num)
    if t['telop'] == '晴れ':
        weather_num = 0
    elif t['telop'] == '晴時々曇':
        weather_num = 1
    elif t['telop'] == '曇時々晴':
        weather_num = 2
    elif t['telop'] == '雨':
        weather_num = 3
    else:
        weather_num = 4
    # 古い画像を削除
    canvas.delete('all')
    # 画像を表示
    canvas.create_image(280, 100, image=img_weather[weather_num])
    label["text"] = t['dateLabel'] + 'の天気は「' + t['telop'] + '」です'
    label.update()
# 天気情報を取得する
def display_weather(date_num):
    # 天気のURL設定 city_numberには都市の番号を指定
    url = "http://weather.livedoor.com/forecast/webservice/json/v1?city=%s" % 130010
    # URLを取得
    response = requests.get(url)
    # URL取得結果のチェック
    response.raise_for_status()
    # 天気データを読み込む
    return json.loads(response.text)['forecasts'][date_num]
# キャンバスの表示
root = tkinter.Tk()
# タイトルの設定
root.title("お天気GUI")
root.resizable(False, False)
# キャンバスのサイズ設定
canvas = tkinter.Canvas(root, width=600, height=600)
# キャンバスの表示
canvas.pack()
# 文字を表示する
label = tkinter.Label(root, text="ボタンをクリックしてください", font=("Times New Roman", 25), bg="white")
label.place(x=30, y=150)
# ボタンを表示する
button = tkinter.Button(root, text="今日の天気", font=("Times New Roman", 20), command=today_weather, fg="skyblue")
button2 = tkinter.Button(root, text="明日の天気", font=("Times New Roman", 20), command=yesterday_weather, fg="skyblue")
button.place(x=200, y=300)
button2.place(x=200, y=350)
img_weather = [
    tkinter.PhotoImage(file="img/sunny.png"),
    tkinter.PhotoImage(file="img/sunny_sometimes_cloudy.png"),
    tkinter.PhotoImage(file="img/cloudy_sometimes_sunny.png"),
    tkinter.PhotoImage(file="img/rainy.png"),
    tkinter.PhotoImage(file="img/cloudy.png")
]
root.mainloop()

上記プログラムを例にプログラムを読む手順を紹介します。
Pythonのコードを読む手順は以下の通りです。

・プログラムを実際に動かす
・ブロック単位で処理を見る
・ステップ単位で処理を見る

◆実行例
明日の天気

プログラムを実際に動かす

プログラムを動かす時には以下のことをチェックしておきます。

・どのようにオブジェクト(文字・画像・背景など)が表示されるか
・どのような操作ができるか
・操作した結果オブジェクトがどう変化するか

ざっくりとでいいので以下のように表にまとめておきましょう。

操作実行結果
初期状態「ボタンをクリックしてください」という文字を表示
今日の天気ボタンをクリック今日の天気を画像と文字で表示
明日の天気ボタンをクリック明日の天気を画像と文字で表示

飽くまで読むときの参考資料なので厳密にやる必要はありません。
わかる範囲でまとめておけばOKです。

ブロック単位で処理を見る

ブロックというのは文章で言うところの段落のようなもので、「特定の目的のために書かれた処理のグループ」です。
プログラムはこのブロックの連続で書かれています。
最初から1stepずつ見ていくとプログラムの全体が見えにくくなります。なので最初はブロック単位で見ていきましょう
ブロック単位で見ていく場合もいきなりコードを読むのではなく、実際に動かしてみるのがおすすめです
実際に動かす方法としては以下の2つがあります。

・前後にprint文を入れてパラメータの変化を見る
・処理を理解したいブロックの部分だけ切り出して実際に動かす

前者は値の変化を見たいブロックの前後にprint文を入れて値の変化を見る方法です。

# ~前のブロック~
# 変更前の値をチェック
print(a)
print(b)
# ブロック開始
a = 2
b = 3
# ブロック終了
# 変更後の値をチェック
print(a)
print(b)
# ~次のブロック~

後者はチェックしたい処理だけ切り出して処理を見る方法です。ただし、ただ切り出すだけでは動かない場合も多いので、パラメータの設定は必要です。
また、うまく動かない場合は切り出す範囲の調整をしましょう。

# パラメータの設定
a = 0
b = 0
# ブロック開始
a = 2
b = 3
# ブロック終了
# 処理後の値をチェック
print(a)
print(b)

ブロックを見るときに意識することは以下の通り。

・どんな値を入れるとうまく動作するか
・どんな場合にエラーとなるか
・値を変えると結果が変わるか

などいろいろなパラメータを入れて試してみましょう。
慣れてきたら最初からコードを読んで処理を理解するのもありです。
サンプルプログラムは以下のようにブロックわけしました。

# ブロック1:import
import tkinter
import requests
import json
# ブロック2:今日の天気を表示関数
# 今日の天気を表示
def today_weather():
    update_weather(0)
# ブロック3:明日の天気を表示関数
# 明日の天気を表示
def yesterday_weather():
    # ラベルにメッセージを設定
    update_weather(1)
# ブロック4:天気の文字と画像を設定する関数
# 今日の天気を表示
def update_weather(date_num):
    # ラベルにメッセージを設定
    t = display_weather(date_num)
    if t['telop'] == '晴れ':
        weather_num = 0
    elif t['telop'] == '晴時々曇':
        weather_num = 1
    elif t['telop'] == '曇時々晴':
        weather_num = 2
    elif t['telop'] == '雨':
        weather_num = 3
    else:
        weather_num = 4
    # 古い画像を削除
    canvas.delete('all')
    # 画像を表示
    canvas.create_image(280, 100, image=img_weather[weather_num])
    label["text"] = t['dateLabel'] + 'の天気は「' + t['telop'] + '」です'
    label.update()
# ブロック5:天気情報をWebページから表示する関数
# 天気情報を取得する
def display_weather(date_num):
    # 天気のURL設定 city_numberには都市の番号を指定
    url = "http://weather.livedoor.com/forecast/webservice/json/v1?city=%s" % 130010
    # URLを取得
    response = requests.get(url)
    # URL取得結果のチェック
    response.raise_for_status()
    # 天気データを読み込む
    return json.loads(response.text)['forecasts'][date_num]
# ブロック6:キャンバスの設定
# キャンバスの表示
root = tkinter.Tk()
# タイトルの設定
root.title("お天気GUI")
root.resizable(False, False)
# キャンバスのサイズ設定
canvas = tkinter.Canvas(root, width=600, height=600)
# キャンバスの表示
canvas.pack()
# ブロック7:文字や画像の設定
# 文字を表示する
label = tkinter.Label(root, text="ボタンをクリックしてください", font=("Times New Roman", 25), bg="white")
label.place(x=30, y=150)
# ボタンを表示する
button = tkinter.Button(root, text="今日の天気", font=("Times New Roman", 20), command=today_weather, fg="skyblue")
button2 = tkinter.Button(root, text="明日の天気", font=("Times New Roman", 20), command=yesterday_weather, fg="skyblue")
button.place(x=200, y=300)
button2.place(x=200, y=350)
# ブロック8:画像のパラメータ設定
img_weather = [
    tkinter.PhotoImage(file="img/sunny.png"),
    tkinter.PhotoImage(file="img/sunny_sometimes_cloudy.png"),
    tkinter.PhotoImage(file="img/cloudy_sometimes_sunny.png"),
    tkinter.PhotoImage(file="img/rainy.png"),
    tkinter.PhotoImage(file="img/cloudy.png")
]
# ブロック9:GUI表示
root.mainloop()

ブロックわけもざっくりとでよいです。
ブロックわけが終わったらブロック単位で見ていきましょう。
例えば上記例で、ブロック4を見る場合は以下の通り。
print文でブロック中で値が変更される変数についてチェックします。

def update_weather(date_num):
    img_weather[weather_num] = ""
    label["text"]=""
    # ラベルにメッセージを設定
    t = display_weather(date_num)
    if t['telop'] == '晴れ':
        weather_num = 0
    elif t['telop'] == '晴時々曇':
        weather_num = 1
    elif t['telop'] == '曇時々晴':
        weather_num = 2
    elif t['telop'] == '雨':
        weather_num = 3
    else:
        weather_num = 4
    # 古い画像を削除
    canvas.delete('all')
    # 画像を表示
    canvas.create_image(280, 100, image=img_weather[weather_num])
    label["text"] = t['dateLabel'] + 'の天気は「' + t['telop'] + '」です'
    label.update()
    print(img_weather[weather_num])
    print(label["text"])

◆実行結果
pyimage4
今日の天気は「雨」です
上記のように、処理を行った結果値がどのように変化するかチェックします。
値の変化から「このブロックは〇〇をする機能ではないか」というあたりをつけましょう。
また、「ブロックを消すとプログラムがどう変化するか」ということを見ておくと各ブロックの役割が理解しやすいです。
「ここを消すと画像が消えるのか。ということはここは画像を管理している」
「ここを消すと立ち上がりすらしない。表示を制御している部分かな?」
のようにコードと実際の動きの対応関係を理解しましょう。

ステップ単位で処理を見る

ブロック単位の動きが理解できてきたら次は1処理単位に見ていきます。
ステップ単位で見る場合も実際に動かしてみるのがおすすめです。

・前後に処理を置く
・入力コンソールで実行する

1stepずつ見る場合はブロックと同様前後にprint文を置く方法もありますが、入力コンソールを活用する方法もあります
ターミナルアプリで「python」と打ち込むとPythonの入力コンソールが開きます。
入力コンソールではPythonのコードがステップ単位で入力できます。
最初は入力コンソールでいろいろ試してみましょう。
慣れてきたらいきなり1行ずつ読んでいくのもありです。

終わりに

ソースコードを読むと聞くといきなりコードを読んでしまう人がいるかもしれませんが、動きを知らないままコードだけ読んでもあまり意味はありません
まずは実際に動かしてプログラムの動きを観察しましょう。
実際の動きがわかればソースコードとの対応関係も理解しやすくなりますし、プログラムの目的や処理の意図が理解しやすくなります。
ブロック単位で見ていく場合やステップ単位で見ていく場合も実際に動かして対応関係を見ていくのがおすすめです
Pythonの勉強方法>>Python入門者のための100日勉強方法
おすすめ記事>>PythonにおすすめのノートPC4選+パソコンの選び方