boolとNone
このレッスンで作るもの — 「はい・いいえ」を表す
boolと、「まだ何もない」を表すNoneを覚え、支払状態を型ごと表示します。
bool と None
おこづかい帳に「もう払ったかどうか」を持たせたいとします。値は 2 つしかありません。払った、まだ払っていない。この 2 択のために Python が用意しているのが bool という型です。
さらにもう 1 つ、「そもそもまだ入力されていない」という状態もあります。払ったとも払っていないとも言えない、空っぽの状態です。これを表すのが None です。
「はい」「いいえ」「未入力」は 3 つとも別の状態です。未入力を「いいえ」で代用すると、あとで区別が付かなくなります。最初から
Noneで分けておきます。
True と False
bool の値は True と False の 2 つだけです。先頭が大文字である点に注意します。
paid = True
unpaid = False
print(type(paid).__name__)bool と表示されます。true と小文字で書くと NameError になります。他の言語から来た人がいちばん引っかかるところです。
クオートで囲んだ "True" は、見た目こそ同じですが str です。まったくの別物なので、混ぜないよう気をつけます。
print(type(True).__name__)
print(type("True").__name__)上は bool、下は str です。前々回の type_name がさっそく役に立ちます。
None
None は「値がない」ことを表す特別な値です。これも先頭が大文字で、型は NoneType という名前になります。
paid = None
print(type(paid).__name__)NoneType と表示されます。None は 0 でも空文字でもありません。「何も入っていない」という状態そのものを表す値です。
第 1 章で、return を書かない関数は None を返すという話がありました。あの None と同じものです。
0 と False は違う
0 と False は近い意味に見えますが、型が違います。
print(type(0).__name__)
print(type(False).__name__)int と bool です。金額の 0 は「0 円使った」という立派な数値で、「いいえ」ではありません。この区別を崩すと、0 円の記録が消えるようなバグにつながります。
「空っぽ」を表す値は
0""NoneFalseと 4 つもあります。どれを使うかは意味で決めます。金額なら0、品名なら""、未入力ならNone、判定結果ならFalseです。
str はどれも文字にできる
前のレッスンで見たとおり、str はどんな値でも文字列にできます。True も None も例外ではありません。
print(str(True))
print(str(False))
print(str(None))True False None と、そのままの見た目で表示されます。この性質を使えば、bool や None を含んだメッセージが + の連結だけで組み立てられます。
動きを追ってみる
payment_status(None) を呼んだときの流れです。
- 引数
paidにNoneが入る str(paid)が"None"という文字列を作るtype(paid).__name__が"NoneType"という文字列を作る"支払 "と"None"と" 型 "と"NoneType"が連結される"支払 None 型 NoneType"が戻り値になる
「払ったなら支払済みと出したい」と思うかもしれませんが、値によって出す文字を変えるには条件分岐が必要です。それは第 4 章の if で扱います。今日は状態と型をそのまま並べて確かめるところまでです。
第 3 章では
paid == Trueのように値を比べる方法を、第 4 章ではその結果で処理を分ける方法を扱います。boolはその 2 つの章で主役になる型です。
よくある間違い
- 小文字で書く —
trueやnoneはNameErrorです。TrueFalseNoneはすべて先頭が大文字です。 - クオートで囲む —
"True"はstrです。boolがほしいときはクオートを付けません。 Noneを 0 や空文字と同じに扱う — 型が違うので、typeの結果もstrにしたときの見た目も変わります。未入力を表したいときだけNoneを使います。
やってみよう
関数 payment_status を実装してください。引数 paid を 1 つ受け取り、その値と型名を並べた文字列を返します。
形は "支払 " + 値の文字列 + " 型 " + 型名です。payment_status(True) は "支払 True 型 bool"、payment_status(None) は "支払 None 型 NoneType" になります。
値の文字列は str(paid)、型名は type(paid).__name__ で取れます。どちらもここまでのレッスンで出てきた道具です。0 や "True" を渡すと型名だけが変わることも、テストで確かめてみてください。
要件
- 関数名は payment_status で、引数は paid の1つ
- 値の部分は str(paid) で文字列にする
- 型名の部分は type(paid).name で取り出す
- "支払 " と " 型 " の半角スペースの位置を変えない
入出力例
payment_status(true) → "支払 True 型 bool"
payment_status(false) → "支払 False 型 bool"
payment_status(null) → "支払 None 型 NoneType"
payment_status(0) → "支払 0 型 int"
payment_status("True") → "支払 True 型 str"