実行順序

このレッスンで作るもの — コードが上から順に走ることを、レシート 3 行を組み立てながら体で覚えます。

実行順序

Python はソースコードを 上から下へ、1 行ずつ 実行します。当たり前に聞こえますが、この一点を押さえていないとエラーの読み方も直し方も分かりません。

print("1 行目") print("2 行目") print("3 行目")

表示は 1 行目 2 行目 3 行目 の順です。書いた順にしか動かないので、3 行目 を先に出したければコードの位置そのものを入れ替えます。

プログラムは書いた順にしか動きません。逆に言えば、書いた順を追えば必ず動きを説明できます。「なぜか動かない」と感じたときは、上から 1 行ずつ指でなぞってみてください。

定義してから呼ぶ

順番の規則は、関数にも効きます。def で関数を作る行より でその関数を呼ぶと、まだ存在しないものを呼んだことになり NameError が出ます。

def title(): return "=== おこづかい帳 ===" print(title())

この並びは正しく動きます。def の行が先に実行されて title という名前が用意され、そのあとで print(title()) が走るからです。逆に print(title()) を先頭に書くと落ちます。

def の行が実行されるのは「関数を作る」ところまでで、中身の return はまだ動きません。中身が動くのは title() と呼び出したその瞬間です。

diagram (will load when visible)

return より下は動かない

関数の中で return に到達すると、そこで関数は 終わります。下に何行書いてあっても実行されません。

def title(): return "=== おこづかい帳 ===" print("ここは絶対に表示されない")

print の行は永遠に出番がありません。エラーにはならず、ただ黙って無視されます。「書いたのに動かない」の原因がこれ、ということが本当によくあります。

return は関数の出口です。出口を通ったあとの部屋は使われません。1 つの関数に return を複数書くこともできますが、実際に通るのは最初に到達した 1 つだけです。

順番どおりに組み立てる

今回は 3 行のレシートを 1 本の文字列で返します。行の区切りには 改行文字 \n を使います。バックスラッシュと n の 2 文字で、1 つの改行を表します。

def receipt_lines(name, price_text): return "=== おこづかい帳 ===" + "\n" + name + " " + price_text + "円" + "\n" + "--- ここまで ---"

receipt_lines("りんご", "120") を呼ぶと、下記の 3 行になります。

=== おこづかい帳 === りんご 120--- ここまで ---

連結は左から順に進むので、書いた順がそのまま表示の順になります。見出しを先に書けば見出しが上に、--- ここまで --- を最後に書けばそれが下に来ます。

末尾に \n は付けません。最後の行のうしろに改行を足すと、見た目には分からない余分な空行が入り、テストが落ちます。

順番を入れ替えるとどうなるか

試しに、見出しと品名の行を逆に書いてみます。

def receipt_lines(name, price_text): return name + " " + price_text + "円" + "\n" + "=== おこづかい帳 ===" + "\n" + "--- ここまで ---"

エラーは出ません。ただ、品名が一番上に来た別のレシートができるだけです。Python は「意図」を読んでくれるわけではなく、書かれた順にひたすら従います。正しく動かすとは、正しい順番で書くことにほかなりません。

エラーが出ないからといって正しいとは限りません。順番の間違いは静かに間違った結果を返します。テストケースを用意しておくと、この手の静かな間違いを機械が見つけてくれます。

よくある間違い

  1. 末尾に余分な \n を付ける+ "\n" で締めくくると、目に見えない差でテストが失敗します。改行は行と行の にだけ入れます。
  2. \n を全角で書く¥n や全角の n では改行になりません。半角のバックスラッシュと半角の n を使います。日本語キーボードでは ¥ キーで入力できます。
  3. 関数を定義する前に呼ぶdef より上で呼び出すと NameError になります。定義が先、呼び出しがあと、という順番を守ります。

やってみよう

関数 receipt_lines を実装してください。引数は品名 name と金額の文字列 price_text の 2 つです。下記の 3 行を \n でつないだ 1 本の文字列を return します。

1 行目は === おこづかい帳 ===、2 行目は 品名 金額円、3 行目は --- ここまで --- です。ハイフンは半角 3 つで、内側は半角スペース 1 つずつ空けます。末尾に改行は付けません。

要件

  1. 関数名は receipt_lines で、引数は name と price_text の2つ
  2. 1行目は "= おこづかい帳 ="、3行目は "--- ここまで ---" にする
  3. 2行目は品名と金額を半角スペースでつなぎ末尾に「円」を付ける
  4. 行の区切りは \n を使い、末尾には改行を付けない

入出力例

receipt_lines("りんご", "120") → "=== おこづかい帳 === りんご 120--- ここまで ---" receipt_lines("牛乳", "198") → "=== おこづかい帳 === 牛乳 198--- ここまで ---" receipt_lines("ノート", "0") → "=== おこづかい帳 === ノート 0--- ここまで ---" receipt_lines("", "50") → "=== おこづかい帳 === 50--- ここまで ---" receipt_lines("チョコレートアイス", "298") → "=== おこづかい帳 === チョコレートアイス 298--- ここまで ---"

ヒント

生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア
編集 LuaGate編集部
main.py
main.py
学習モード

メモ

実行順序

⌘S で保存